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