]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/lldb/source/Utility/Stream.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / lldb / source / Utility / Stream.cpp
1 //===-- Stream.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/Utility/Stream.h"
11
12 #include "lldb/Utility/Endian.h"
13 #include "lldb/Utility/VASPrintf.h"
14 #include "llvm/ADT/SmallString.h"
15 #include "llvm/Support/LEB128.h"
16
17 #include <string>
18
19 #include <inttypes.h>
20 #include <stddef.h>
21
22 using namespace lldb;
23 using namespace lldb_private;
24
25 Stream::Stream(uint32_t flags, uint32_t addr_size, ByteOrder byte_order)
26     : m_flags(flags), m_addr_size(addr_size), m_byte_order(byte_order),
27       m_indent_level(0), m_forwarder(*this) {}
28
29 Stream::Stream()
30     : m_flags(0), m_addr_size(4), m_byte_order(endian::InlHostByteOrder()),
31       m_indent_level(0), m_forwarder(*this) {}
32
33 //------------------------------------------------------------------
34 // Destructor
35 //------------------------------------------------------------------
36 Stream::~Stream() {}
37
38 ByteOrder Stream::SetByteOrder(ByteOrder byte_order) {
39   ByteOrder old_byte_order = m_byte_order;
40   m_byte_order = byte_order;
41   return old_byte_order;
42 }
43
44 //------------------------------------------------------------------
45 // Put an offset "uval" out to the stream using the printf format in "format".
46 //------------------------------------------------------------------
47 void Stream::Offset(uint32_t uval, const char *format) { Printf(format, uval); }
48
49 //------------------------------------------------------------------
50 // Put an SLEB128 "uval" out to the stream using the printf format in "format".
51 //------------------------------------------------------------------
52 size_t Stream::PutSLEB128(int64_t sval) {
53   if (m_flags.Test(eBinary))
54     return llvm::encodeSLEB128(sval, m_forwarder);
55   else
56     return Printf("0x%" PRIi64, sval);
57 }
58
59 //------------------------------------------------------------------
60 // Put an ULEB128 "uval" out to the stream using the printf format in "format".
61 //------------------------------------------------------------------
62 size_t Stream::PutULEB128(uint64_t uval) {
63   if (m_flags.Test(eBinary))
64     return llvm::encodeULEB128(uval, m_forwarder);
65   else
66     return Printf("0x%" PRIx64, uval);
67 }
68
69 //------------------------------------------------------------------
70 // Print a raw NULL terminated C string to the stream.
71 //------------------------------------------------------------------
72 size_t Stream::PutCString(llvm::StringRef str) {
73   size_t bytes_written = 0;
74   bytes_written = Write(str.data(), str.size());
75
76   // when in binary mode, emit the NULL terminator
77   if (m_flags.Test(eBinary))
78     bytes_written += PutChar('\0');
79   return bytes_written;
80 }
81
82 //------------------------------------------------------------------
83 // Print a double quoted NULL terminated C string to the stream using the
84 // printf format in "format".
85 //------------------------------------------------------------------
86 void Stream::QuotedCString(const char *cstr, const char *format) {
87   Printf(format, cstr);
88 }
89
90 //------------------------------------------------------------------
91 // Put an address "addr" out to the stream with optional prefix and suffix
92 // strings.
93 //------------------------------------------------------------------
94 void Stream::Address(uint64_t addr, uint32_t addr_size, const char *prefix,
95                      const char *suffix) {
96   if (prefix == nullptr)
97     prefix = "";
98   if (suffix == nullptr)
99     suffix = "";
100   //    int addr_width = m_addr_size << 1;
101   //    Printf ("%s0x%0*" PRIx64 "%s", prefix, addr_width, addr, suffix);
102   Printf("%s0x%0*" PRIx64 "%s", prefix, addr_size * 2, (uint64_t)addr, suffix);
103 }
104
105 //------------------------------------------------------------------
106 // Put an address range out to the stream with optional prefix and suffix
107 // strings.
108 //------------------------------------------------------------------
109 void Stream::AddressRange(uint64_t lo_addr, uint64_t hi_addr,
110                           uint32_t addr_size, const char *prefix,
111                           const char *suffix) {
112   if (prefix && prefix[0])
113     PutCString(prefix);
114   Address(lo_addr, addr_size, "[");
115   Address(hi_addr, addr_size, "-", ")");
116   if (suffix && suffix[0])
117     PutCString(suffix);
118 }
119
120 size_t Stream::PutChar(char ch) { return Write(&ch, 1); }
121
122 //------------------------------------------------------------------
123 // Print some formatted output to the stream.
124 //------------------------------------------------------------------
125 size_t Stream::Printf(const char *format, ...) {
126   va_list args;
127   va_start(args, format);
128   size_t result = PrintfVarArg(format, args);
129   va_end(args);
130   return result;
131 }
132
133 //------------------------------------------------------------------
134 // Print some formatted output to the stream.
135 //------------------------------------------------------------------
136 size_t Stream::PrintfVarArg(const char *format, va_list args) {
137   llvm::SmallString<1024> buf;
138   VASprintf(buf, format, args);
139
140   // Include the NULL termination byte for binary output
141   size_t length = buf.size();
142   if (m_flags.Test(eBinary))
143     ++length;
144   return Write(buf.c_str(), length);
145 }
146
147 //------------------------------------------------------------------
148 // Print and End of Line character to the stream
149 //------------------------------------------------------------------
150 size_t Stream::EOL() { return PutChar('\n'); }
151
152 //------------------------------------------------------------------
153 // Indent the current line using the current indentation level and print an
154 // optional string following the indentation spaces.
155 //------------------------------------------------------------------
156 size_t Stream::Indent(const char *s) {
157   return Printf("%*.*s%s", m_indent_level, m_indent_level, "", s ? s : "");
158 }
159
160 size_t Stream::Indent(llvm::StringRef str) {
161   return Printf("%*.*s%s", m_indent_level, m_indent_level, "",
162                 str.str().c_str());
163 }
164
165 //------------------------------------------------------------------
166 // Stream a character "ch" out to this stream.
167 //------------------------------------------------------------------
168 Stream &Stream::operator<<(char ch) {
169   PutChar(ch);
170   return *this;
171 }
172
173 //------------------------------------------------------------------
174 // Stream the NULL terminated C string out to this stream.
175 //------------------------------------------------------------------
176 Stream &Stream::operator<<(const char *s) {
177   Printf("%s", s);
178   return *this;
179 }
180
181 Stream &Stream::operator<<(llvm::StringRef str) {
182   Write(str.data(), str.size());
183   return *this;
184 }
185
186 //------------------------------------------------------------------
187 // Stream the pointer value out to this stream.
188 //------------------------------------------------------------------
189 Stream &Stream::operator<<(const void *p) {
190   Printf("0x%.*tx", (int)sizeof(const void *) * 2, (ptrdiff_t)p);
191   return *this;
192 }
193
194 //------------------------------------------------------------------
195 // Stream a uint8_t "uval" out to this stream.
196 //------------------------------------------------------------------
197 Stream &Stream::operator<<(uint8_t uval) {
198   PutHex8(uval);
199   return *this;
200 }
201
202 //------------------------------------------------------------------
203 // Stream a uint16_t "uval" out to this stream.
204 //------------------------------------------------------------------
205 Stream &Stream::operator<<(uint16_t uval) {
206   PutHex16(uval, m_byte_order);
207   return *this;
208 }
209
210 //------------------------------------------------------------------
211 // Stream a uint32_t "uval" out to this stream.
212 //------------------------------------------------------------------
213 Stream &Stream::operator<<(uint32_t uval) {
214   PutHex32(uval, m_byte_order);
215   return *this;
216 }
217
218 //------------------------------------------------------------------
219 // Stream a uint64_t "uval" out to this stream.
220 //------------------------------------------------------------------
221 Stream &Stream::operator<<(uint64_t uval) {
222   PutHex64(uval, m_byte_order);
223   return *this;
224 }
225
226 //------------------------------------------------------------------
227 // Stream a int8_t "sval" out to this stream.
228 //------------------------------------------------------------------
229 Stream &Stream::operator<<(int8_t sval) {
230   Printf("%i", (int)sval);
231   return *this;
232 }
233
234 //------------------------------------------------------------------
235 // Stream a int16_t "sval" out to this stream.
236 //------------------------------------------------------------------
237 Stream &Stream::operator<<(int16_t sval) {
238   Printf("%i", (int)sval);
239   return *this;
240 }
241
242 //------------------------------------------------------------------
243 // Stream a int32_t "sval" out to this stream.
244 //------------------------------------------------------------------
245 Stream &Stream::operator<<(int32_t sval) {
246   Printf("%i", (int)sval);
247   return *this;
248 }
249
250 //------------------------------------------------------------------
251 // Stream a int64_t "sval" out to this stream.
252 //------------------------------------------------------------------
253 Stream &Stream::operator<<(int64_t sval) {
254   Printf("%" PRIi64, sval);
255   return *this;
256 }
257
258 //------------------------------------------------------------------
259 // Get the current indentation level
260 //------------------------------------------------------------------
261 int Stream::GetIndentLevel() const { return m_indent_level; }
262
263 //------------------------------------------------------------------
264 // Set the current indentation level
265 //------------------------------------------------------------------
266 void Stream::SetIndentLevel(int indent_level) { m_indent_level = indent_level; }
267
268 //------------------------------------------------------------------
269 // Increment the current indentation level
270 //------------------------------------------------------------------
271 void Stream::IndentMore(int amount) { m_indent_level += amount; }
272
273 //------------------------------------------------------------------
274 // Decrement the current indentation level
275 //------------------------------------------------------------------
276 void Stream::IndentLess(int amount) {
277   if (m_indent_level >= amount)
278     m_indent_level -= amount;
279   else
280     m_indent_level = 0;
281 }
282
283 //------------------------------------------------------------------
284 // Get the address size in bytes
285 //------------------------------------------------------------------
286 uint32_t Stream::GetAddressByteSize() const { return m_addr_size; }
287
288 //------------------------------------------------------------------
289 // Set the address size in bytes
290 //------------------------------------------------------------------
291 void Stream::SetAddressByteSize(uint32_t addr_size) { m_addr_size = addr_size; }
292
293 //------------------------------------------------------------------
294 // The flags get accessor
295 //------------------------------------------------------------------
296 Flags &Stream::GetFlags() { return m_flags; }
297
298 //------------------------------------------------------------------
299 // The flags const get accessor
300 //------------------------------------------------------------------
301 const Flags &Stream::GetFlags() const { return m_flags; }
302
303 //------------------------------------------------------------------
304 // The byte order get accessor
305 //------------------------------------------------------------------
306
307 lldb::ByteOrder Stream::GetByteOrder() const { return m_byte_order; }
308
309 size_t Stream::PrintfAsRawHex8(const char *format, ...) {
310   va_list args;
311   va_start(args, format);
312
313   llvm::SmallString<1024> buf;
314   VASprintf(buf, format, args);
315
316   ByteDelta delta(*this);
317   for (char C : buf)
318     _PutHex8(C, false);
319
320   va_end(args);
321
322   return *delta;
323 }
324
325 size_t Stream::PutNHex8(size_t n, uint8_t uvalue) {
326   ByteDelta delta(*this);
327   for (size_t i = 0; i < n; ++i)
328     _PutHex8(uvalue, false);
329   return *delta;
330 }
331
332 void Stream::_PutHex8(uint8_t uvalue, bool add_prefix) {
333   if (m_flags.Test(eBinary)) {
334     Write(&uvalue, 1);
335   } else {
336     if (add_prefix)
337       PutCString("0x");
338
339     static char g_hex_to_ascii_hex_char[16] = {'0', '1', '2', '3', '4', '5',
340                                                '6', '7', '8', '9', 'a', 'b',
341                                                'c', 'd', 'e', 'f'};
342     char nibble_chars[2];
343     nibble_chars[0] = g_hex_to_ascii_hex_char[(uvalue >> 4) & 0xf];
344     nibble_chars[1] = g_hex_to_ascii_hex_char[(uvalue >> 0) & 0xf];
345     Write(nibble_chars, sizeof(nibble_chars));
346   }
347 }
348
349 size_t Stream::PutHex8(uint8_t uvalue) {
350   ByteDelta delta(*this);
351   _PutHex8(uvalue, false);
352   return *delta;
353 }
354
355 size_t Stream::PutHex16(uint16_t uvalue, ByteOrder byte_order) {
356   ByteDelta delta(*this);
357
358   if (byte_order == eByteOrderInvalid)
359     byte_order = m_byte_order;
360
361   if (byte_order == eByteOrderLittle) {
362     for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
363       _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
364   } else {
365     for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
366       _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
367   }
368   return *delta;
369 }
370
371 size_t Stream::PutHex32(uint32_t uvalue, ByteOrder byte_order) {
372   ByteDelta delta(*this);
373
374   if (byte_order == eByteOrderInvalid)
375     byte_order = m_byte_order;
376
377   if (byte_order == eByteOrderLittle) {
378     for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
379       _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
380   } else {
381     for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
382       _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
383   }
384   return *delta;
385 }
386
387 size_t Stream::PutHex64(uint64_t uvalue, ByteOrder byte_order) {
388   ByteDelta delta(*this);
389
390   if (byte_order == eByteOrderInvalid)
391     byte_order = m_byte_order;
392
393   if (byte_order == eByteOrderLittle) {
394     for (size_t byte = 0; byte < sizeof(uvalue); ++byte)
395       _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
396   } else {
397     for (size_t byte = sizeof(uvalue) - 1; byte < sizeof(uvalue); --byte)
398       _PutHex8((uint8_t)(uvalue >> (byte * 8)), false);
399   }
400   return *delta;
401 }
402
403 size_t Stream::PutMaxHex64(uint64_t uvalue, size_t byte_size,
404                            lldb::ByteOrder byte_order) {
405   switch (byte_size) {
406   case 1:
407     return PutHex8((uint8_t)uvalue);
408   case 2:
409     return PutHex16((uint16_t)uvalue, byte_order);
410   case 4:
411     return PutHex32((uint32_t)uvalue, byte_order);
412   case 8:
413     return PutHex64(uvalue, byte_order);
414   }
415   return 0;
416 }
417
418 size_t Stream::PutPointer(void *ptr) {
419   return PutRawBytes(&ptr, sizeof(ptr), endian::InlHostByteOrder(),
420                      endian::InlHostByteOrder());
421 }
422
423 size_t Stream::PutFloat(float f, ByteOrder byte_order) {
424   if (byte_order == eByteOrderInvalid)
425     byte_order = m_byte_order;
426
427   return PutRawBytes(&f, sizeof(f), endian::InlHostByteOrder(), byte_order);
428 }
429
430 size_t Stream::PutDouble(double d, ByteOrder byte_order) {
431   if (byte_order == eByteOrderInvalid)
432     byte_order = m_byte_order;
433
434   return PutRawBytes(&d, sizeof(d), endian::InlHostByteOrder(), byte_order);
435 }
436
437 size_t Stream::PutLongDouble(long double ld, ByteOrder byte_order) {
438   if (byte_order == eByteOrderInvalid)
439     byte_order = m_byte_order;
440
441   return PutRawBytes(&ld, sizeof(ld), endian::InlHostByteOrder(), byte_order);
442 }
443
444 size_t Stream::PutRawBytes(const void *s, size_t src_len,
445                            ByteOrder src_byte_order, ByteOrder dst_byte_order) {
446   ByteDelta delta(*this);
447
448   if (src_byte_order == eByteOrderInvalid)
449     src_byte_order = m_byte_order;
450
451   if (dst_byte_order == eByteOrderInvalid)
452     dst_byte_order = m_byte_order;
453
454   const uint8_t *src = (const uint8_t *)s;
455   bool binary_was_set = m_flags.Test(eBinary);
456   if (!binary_was_set)
457     m_flags.Set(eBinary);
458   if (src_byte_order == dst_byte_order) {
459     for (size_t i = 0; i < src_len; ++i)
460       _PutHex8(src[i], false);
461   } else {
462     for (size_t i = src_len - 1; i < src_len; --i)
463       _PutHex8(src[i], false);
464   }
465   if (!binary_was_set)
466     m_flags.Clear(eBinary);
467
468   return *delta;
469 }
470
471 size_t Stream::PutBytesAsRawHex8(const void *s, size_t src_len,
472                                  ByteOrder src_byte_order,
473                                  ByteOrder dst_byte_order) {
474   ByteDelta delta(*this);
475   if (src_byte_order == eByteOrderInvalid)
476     src_byte_order = m_byte_order;
477
478   if (dst_byte_order == eByteOrderInvalid)
479     dst_byte_order = m_byte_order;
480
481   const uint8_t *src = (const uint8_t *)s;
482   bool binary_is_set = m_flags.Test(eBinary);
483   m_flags.Clear(eBinary);
484   if (src_byte_order == dst_byte_order) {
485     for (size_t i = 0; i < src_len; ++i)
486       _PutHex8(src[i], false);
487   } else {
488     for (size_t i = src_len - 1; i < src_len; --i)
489       _PutHex8(src[i], false);
490   }
491   if (binary_is_set)
492     m_flags.Set(eBinary);
493
494   return *delta;
495 }
496
497 size_t Stream::PutCStringAsRawHex8(const char *s) {
498   ByteDelta delta(*this);
499   bool binary_is_set = m_flags.Test(eBinary);
500   m_flags.Clear(eBinary);
501   while(*s) {
502     _PutHex8(*s, false);
503     ++s;
504   }
505   if (binary_is_set)
506     m_flags.Set(eBinary);
507   return *delta;
508 }