]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/lldb/include/lldb/DataFormatters/StringPrinter.h
Fix a memory leak in if_delgroups() introduced in r334118.
[FreeBSD/FreeBSD.git] / contrib / llvm-project / lldb / include / lldb / DataFormatters / StringPrinter.h
1 //===-- StringPrinter.h -----------------------------------------*- 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 #ifndef liblldb_StringPrinter_h_
10 #define liblldb_StringPrinter_h_
11
12 #include <functional>
13 #include <string>
14
15 #include "lldb/lldb-forward.h"
16
17 #include "lldb/Utility/DataExtractor.h"
18
19 namespace lldb_private {
20 namespace formatters {
21 class StringPrinter {
22 public:
23   enum class StringElementType { ASCII, UTF8, UTF16, UTF32 };
24
25   enum class GetPrintableElementType { ASCII, UTF8 };
26
27   class ReadStringAndDumpToStreamOptions {
28   public:
29     ReadStringAndDumpToStreamOptions()
30         : m_location(0), m_process_sp(), m_stream(nullptr), m_prefix_token(),
31           m_suffix_token(), m_quote('"'), m_source_size(0),
32           m_needs_zero_termination(true), m_escape_non_printables(true),
33           m_ignore_max_length(false), m_zero_is_terminator(true),
34           m_language_type(lldb::eLanguageTypeUnknown) {}
35
36     ReadStringAndDumpToStreamOptions(ValueObject &valobj);
37
38     ReadStringAndDumpToStreamOptions &SetLocation(uint64_t l) {
39       m_location = l;
40       return *this;
41     }
42
43     uint64_t GetLocation() const { return m_location; }
44
45     ReadStringAndDumpToStreamOptions &SetProcessSP(lldb::ProcessSP p) {
46       m_process_sp = p;
47       return *this;
48     }
49
50     lldb::ProcessSP GetProcessSP() const { return m_process_sp; }
51
52     ReadStringAndDumpToStreamOptions &SetStream(Stream *s) {
53       m_stream = s;
54       return *this;
55     }
56
57     Stream *GetStream() const { return m_stream; }
58
59     ReadStringAndDumpToStreamOptions &SetPrefixToken(const std::string &p) {
60       m_prefix_token = p;
61       return *this;
62     }
63
64     ReadStringAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) {
65       m_prefix_token.clear();
66       return *this;
67     }
68
69     const char *GetPrefixToken() const { return m_prefix_token.c_str(); }
70
71     ReadStringAndDumpToStreamOptions &SetSuffixToken(const std::string &p) {
72       m_suffix_token = p;
73       return *this;
74     }
75
76     ReadStringAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) {
77       m_suffix_token.clear();
78       return *this;
79     }
80
81     const char *GetSuffixToken() const { return m_suffix_token.c_str(); }
82
83     ReadStringAndDumpToStreamOptions &SetQuote(char q) {
84       m_quote = q;
85       return *this;
86     }
87
88     char GetQuote() const { return m_quote; }
89
90     ReadStringAndDumpToStreamOptions &SetSourceSize(uint32_t s) {
91       m_source_size = s;
92       return *this;
93     }
94
95     uint32_t GetSourceSize() const { return m_source_size; }
96
97     ReadStringAndDumpToStreamOptions &SetNeedsZeroTermination(bool z) {
98       m_needs_zero_termination = z;
99       return *this;
100     }
101
102     bool GetNeedsZeroTermination() const { return m_needs_zero_termination; }
103
104     ReadStringAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) {
105       m_zero_is_terminator = e;
106       return *this;
107     }
108
109     bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
110
111     ReadStringAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) {
112       m_escape_non_printables = e;
113       return *this;
114     }
115
116     bool GetEscapeNonPrintables() const { return m_escape_non_printables; }
117
118     ReadStringAndDumpToStreamOptions &SetIgnoreMaxLength(bool e) {
119       m_ignore_max_length = e;
120       return *this;
121     }
122
123     bool GetIgnoreMaxLength() const { return m_ignore_max_length; }
124
125     ReadStringAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) {
126       m_language_type = l;
127       return *this;
128     }
129
130     lldb::LanguageType GetLanguage() const
131
132     {
133       return m_language_type;
134     }
135
136   private:
137     uint64_t m_location;
138     lldb::ProcessSP m_process_sp;
139     Stream *m_stream;
140     std::string m_prefix_token;
141     std::string m_suffix_token;
142     char m_quote;
143     uint32_t m_source_size;
144     bool m_needs_zero_termination;
145     bool m_escape_non_printables;
146     bool m_ignore_max_length;
147     bool m_zero_is_terminator;
148     lldb::LanguageType m_language_type;
149   };
150
151   class ReadBufferAndDumpToStreamOptions {
152   public:
153     ReadBufferAndDumpToStreamOptions()
154         : m_data(), m_stream(nullptr), m_prefix_token(), m_suffix_token(),
155           m_quote('"'), m_source_size(0), m_escape_non_printables(true),
156           m_zero_is_terminator(true), m_is_truncated(false),
157           m_language_type(lldb::eLanguageTypeUnknown) {}
158
159     ReadBufferAndDumpToStreamOptions(ValueObject &valobj);
160
161     ReadBufferAndDumpToStreamOptions(
162         const ReadStringAndDumpToStreamOptions &options);
163
164     ReadBufferAndDumpToStreamOptions &SetData(DataExtractor d) {
165       m_data = d;
166       return *this;
167     }
168
169     lldb_private::DataExtractor GetData() const { return m_data; }
170
171     ReadBufferAndDumpToStreamOptions &SetStream(Stream *s) {
172       m_stream = s;
173       return *this;
174     }
175
176     Stream *GetStream() const { return m_stream; }
177
178     ReadBufferAndDumpToStreamOptions &SetPrefixToken(const std::string &p) {
179       m_prefix_token = p;
180       return *this;
181     }
182
183     ReadBufferAndDumpToStreamOptions &SetPrefixToken(std::nullptr_t) {
184       m_prefix_token.clear();
185       return *this;
186     }
187
188     const char *GetPrefixToken() const { return m_prefix_token.c_str(); }
189
190     ReadBufferAndDumpToStreamOptions &SetSuffixToken(const std::string &p) {
191       m_suffix_token = p;
192       return *this;
193     }
194
195     ReadBufferAndDumpToStreamOptions &SetSuffixToken(std::nullptr_t) {
196       m_suffix_token.clear();
197       return *this;
198     }
199
200     const char *GetSuffixToken() const { return m_suffix_token.c_str(); }
201
202     ReadBufferAndDumpToStreamOptions &SetQuote(char q) {
203       m_quote = q;
204       return *this;
205     }
206
207     char GetQuote() const { return m_quote; }
208
209     ReadBufferAndDumpToStreamOptions &SetSourceSize(uint32_t s) {
210       m_source_size = s;
211       return *this;
212     }
213
214     uint32_t GetSourceSize() const { return m_source_size; }
215
216     ReadBufferAndDumpToStreamOptions &SetEscapeNonPrintables(bool e) {
217       m_escape_non_printables = e;
218       return *this;
219     }
220
221     bool GetEscapeNonPrintables() const { return m_escape_non_printables; }
222
223     ReadBufferAndDumpToStreamOptions &SetBinaryZeroIsTerminator(bool e) {
224       m_zero_is_terminator = e;
225       return *this;
226     }
227
228     bool GetBinaryZeroIsTerminator() const { return m_zero_is_terminator; }
229
230     ReadBufferAndDumpToStreamOptions &SetIsTruncated(bool t) {
231       m_is_truncated = t;
232       return *this;
233     }
234
235     bool GetIsTruncated() const { return m_is_truncated; }
236
237     ReadBufferAndDumpToStreamOptions &SetLanguage(lldb::LanguageType l) {
238       m_language_type = l;
239       return *this;
240     }
241
242     lldb::LanguageType GetLanguage() const
243
244     {
245       return m_language_type;
246     }
247
248   private:
249     DataExtractor m_data;
250     Stream *m_stream;
251     std::string m_prefix_token;
252     std::string m_suffix_token;
253     char m_quote;
254     uint32_t m_source_size;
255     bool m_escape_non_printables;
256     bool m_zero_is_terminator;
257     bool m_is_truncated;
258     lldb::LanguageType m_language_type;
259   };
260
261   // I can't use a std::unique_ptr for this because the Deleter is a template
262   // argument there
263   // and I want the same type to represent both pointers I want to free and
264   // pointers I don't need to free - which is what this class essentially is
265   // It's very specialized to the needs of this file, and not suggested for
266   // general use
267   template <typename T = uint8_t, typename U = char, typename S = size_t>
268   struct StringPrinterBufferPointer {
269   public:
270     typedef std::function<void(const T *)> Deleter;
271
272     StringPrinterBufferPointer(std::nullptr_t ptr)
273         : m_data(nullptr), m_size(0), m_deleter() {}
274
275     StringPrinterBufferPointer(const T *bytes, S size,
276                                Deleter deleter = nullptr)
277         : m_data(bytes), m_size(size), m_deleter(deleter) {}
278
279     StringPrinterBufferPointer(const U *bytes, S size,
280                                Deleter deleter = nullptr)
281         : m_data(reinterpret_cast<const T *>(bytes)), m_size(size),
282           m_deleter(deleter) {}
283
284     StringPrinterBufferPointer(StringPrinterBufferPointer &&rhs)
285         : m_data(rhs.m_data), m_size(rhs.m_size), m_deleter(rhs.m_deleter) {
286       rhs.m_data = nullptr;
287     }
288
289     StringPrinterBufferPointer(const StringPrinterBufferPointer &rhs)
290         : m_data(rhs.m_data), m_size(rhs.m_size), m_deleter(rhs.m_deleter) {
291       rhs.m_data = nullptr; // this is why m_data has to be mutable
292     }
293
294     ~StringPrinterBufferPointer() {
295       if (m_data && m_deleter)
296         m_deleter(m_data);
297       m_data = nullptr;
298     }
299
300     const T *GetBytes() const { return m_data; }
301
302     const S GetSize() const { return m_size; }
303
304     StringPrinterBufferPointer &
305     operator=(const StringPrinterBufferPointer &rhs) {
306       if (m_data && m_deleter)
307         m_deleter(m_data);
308       m_data = rhs.m_data;
309       m_size = rhs.m_size;
310       m_deleter = rhs.m_deleter;
311       rhs.m_data = nullptr;
312       return *this;
313     }
314
315   private:
316     mutable const T *m_data;
317     size_t m_size;
318     Deleter m_deleter;
319   };
320
321   typedef std::function<StringPrinter::StringPrinterBufferPointer<
322       uint8_t, char, size_t>(uint8_t *, uint8_t *, uint8_t *&)>
323       EscapingHelper;
324   typedef std::function<EscapingHelper(GetPrintableElementType)>
325       EscapingHelperGenerator;
326
327   static EscapingHelper
328   GetDefaultEscapingHelper(GetPrintableElementType elem_type);
329
330   template <StringElementType element_type>
331   static bool
332   ReadStringAndDumpToStream(const ReadStringAndDumpToStreamOptions &options);
333
334   template <StringElementType element_type>
335   static bool
336   ReadBufferAndDumpToStream(const ReadBufferAndDumpToStreamOptions &options);
337 };
338
339 } // namespace formatters
340 } // namespace lldb_private
341
342 #endif // liblldb_StringPrinter_h_