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 DumpStringToStreamWithNewline(Stream &strm, const std::string &s,
23                                           bool add_newline_if_empty) {
24   bool add_newline = false;
25   if (s.empty()) {
26     add_newline = add_newline_if_empty;
27   } else {
28     // We already checked for empty above, now make sure there is a newline
29     // in the error, and if there isn't one, add one.
30     strm.Write(s.c_str(), s.size());
31 
32     const char last_char = *s.rbegin();
33     add_newline = last_char != '\n' && last_char != '\r';
34   }
35   if (add_newline)
36     strm.EOL();
37 }
38 
39 CommandReturnObject::CommandReturnObject()
40     : m_out_stream(), m_err_stream(), m_status(eReturnStatusStarted),
41       m_did_change_process_state(false), m_interactive(true),
42       m_abnormal_stop_was_expected(false) {}
43 
44 CommandReturnObject::~CommandReturnObject() {}
45 
46 void CommandReturnObject::AppendErrorWithFormat(const char *format, ...) {
47   if (!format)
48     return;
49   va_list args;
50   va_start(args, format);
51   StreamString sstrm;
52   sstrm.PrintfVarArg(format, args);
53   va_end(args);
54 
55   const std::string &s = sstrm.GetString();
56   if (!s.empty()) {
57     Stream &error_strm = GetErrorStream();
58     error_strm.PutCString("error: ");
59     DumpStringToStreamWithNewline(error_strm, s, false);
60   }
61 }
62 
63 void CommandReturnObject::AppendMessageWithFormat(const char *format, ...) {
64   if (!format)
65     return;
66   va_list args;
67   va_start(args, format);
68   StreamString sstrm;
69   sstrm.PrintfVarArg(format, args);
70   va_end(args);
71 
72   GetOutputStream().Printf("%s", sstrm.GetData());
73 }
74 
75 void CommandReturnObject::AppendWarningWithFormat(const char *format, ...) {
76   if (!format)
77     return;
78   va_list args;
79   va_start(args, format);
80   StreamString sstrm;
81   sstrm.PrintfVarArg(format, args);
82   va_end(args);
83 
84   GetErrorStream().Printf("warning: %s", sstrm.GetData());
85 }
86 
87 void CommandReturnObject::AppendMessage(const char *in_string) {
88   if (!in_string)
89     return;
90   GetOutputStream().Printf("%s\n", in_string);
91 }
92 
93 void CommandReturnObject::AppendWarning(const char *in_string) {
94   if (!in_string || *in_string == '\0')
95     return;
96   GetErrorStream().Printf("warning: %s\n", in_string);
97 }
98 
99 // Similar to AppendWarning, but do not prepend 'warning: ' to message, and
100 // don't append "\n" to the end of it.
101 
102 void CommandReturnObject::AppendRawWarning(const char *in_string) {
103   if (in_string && in_string[0])
104     GetErrorStream().PutCString(in_string);
105 }
106 
107 void CommandReturnObject::AppendError(const char *in_string) {
108   if (!in_string || *in_string == '\0')
109     return;
110   GetErrorStream().Printf("error: %s\n", in_string);
111 }
112 
113 void CommandReturnObject::SetError(const Error &error,
114                                    const char *fallback_error_cstr) {
115   const char *error_cstr = error.AsCString();
116   if (error_cstr == nullptr)
117     error_cstr = fallback_error_cstr;
118   SetError(error_cstr);
119 }
120 
121 void CommandReturnObject::SetError(const char *error_cstr) {
122   if (error_cstr) {
123     AppendError(error_cstr);
124     SetStatus(eReturnStatusFailed);
125   }
126 }
127 
128 // Similar to AppendError, but do not prepend 'Error: ' to message, and
129 // don't append "\n" to the end of it.
130 
131 void CommandReturnObject::AppendRawError(const char *in_string) {
132   if (in_string && in_string[0])
133     GetErrorStream().PutCString(in_string);
134 }
135 
136 void CommandReturnObject::SetStatus(ReturnStatus status) { m_status = status; }
137 
138 ReturnStatus CommandReturnObject::GetStatus() { return m_status; }
139 
140 bool CommandReturnObject::Succeeded() {
141   return m_status <= eReturnStatusSuccessContinuingResult;
142 }
143 
144 bool CommandReturnObject::HasResult() {
145   return (m_status == eReturnStatusSuccessFinishResult ||
146           m_status == eReturnStatusSuccessContinuingResult);
147 }
148 
149 void CommandReturnObject::Clear() {
150   lldb::StreamSP stream_sp;
151   stream_sp = m_out_stream.GetStreamAtIndex(eStreamStringIndex);
152   if (stream_sp)
153     static_cast<StreamString *>(stream_sp.get())->Clear();
154   stream_sp = m_err_stream.GetStreamAtIndex(eStreamStringIndex);
155   if (stream_sp)
156     static_cast<StreamString *>(stream_sp.get())->Clear();
157   m_status = eReturnStatusStarted;
158   m_did_change_process_state = false;
159   m_interactive = true;
160 }
161 
162 bool CommandReturnObject::GetDidChangeProcessState() {
163   return m_did_change_process_state;
164 }
165 
166 void CommandReturnObject::SetDidChangeProcessState(bool b) {
167   m_did_change_process_state = b;
168 }
169 
170 bool CommandReturnObject::GetInteractive() const { return m_interactive; }
171 
172 void CommandReturnObject::SetInteractive(bool b) { m_interactive = b; }
173