diff options
author | Tom Tromey <tom@tromey.com> | 2021-12-31 10:40:02 -0700 |
---|---|---|
committer | Tom Tromey <tom@tromey.com> | 2022-01-05 11:01:02 -0700 |
commit | d53fd721a18f8c827aa69ffbd15abd99641b5e20 (patch) | |
tree | 436641845129a7eb9eb38733a456656da9312366 /gdb/ui-file.c | |
parent | 28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8 (diff) | |
download | gdb-d53fd721a18f8c827aa69ffbd15abd99641b5e20.zip gdb-d53fd721a18f8c827aa69ffbd15abd99641b5e20.tar.gz gdb-d53fd721a18f8c827aa69ffbd15abd99641b5e20.tar.bz2 |
Implement putstr and putstrn in ui_file
In my tour of the ui_file subsystem, I found that fputstr and fputstrn
can be simplified. The _filtered forms are never used (and IMO
unlikely to ever be used) and so can be removed. And, the interface
can be simplified by removing a callback function and moving the
implementation directly to ui_file.
A new self-test is included. Previously, I think nothing was testing
this code.
Regression tested on x86-64 Fedora 34.
Diffstat (limited to 'gdb/ui-file.c')
-rw-r--r-- | gdb/ui-file.c | 69 |
1 files changed, 66 insertions, 3 deletions
diff --git a/gdb/ui-file.c b/gdb/ui-file.c index 57352e4..c6a4888 100644 --- a/gdb/ui-file.c +++ b/gdb/ui-file.c @@ -47,13 +47,15 @@ ui_file::printf (const char *format, ...) void ui_file::putstr (const char *str, int quoter) { - fputstr_unfiltered (str, quoter, this); + while (*str) + printchar (*str++, quoter, false); } void -ui_file::putstrn (const char *str, int n, int quoter) +ui_file::putstrn (const char *str, int n, int quoter, bool async_safe) { - fputstrn_unfiltered (str, n, quoter, fputc_unfiltered, this); + for (int i = 0; i < n; i++) + printchar (str[i], quoter, async_safe); } int @@ -68,6 +70,67 @@ ui_file::vprintf (const char *format, va_list args) vfprintf_unfiltered (this, format, args); } +/* See ui-file.h. */ + +void +ui_file::printchar (int c, int quoter, bool async_safe) +{ + char buf[4]; + int out = 0; + + c &= 0xFF; /* Avoid sign bit follies */ + + if (c < 0x20 /* Low control chars */ + || (c >= 0x7F && c < 0xA0) /* DEL, High controls */ + || (sevenbit_strings && c >= 0x80)) + { /* high order bit set */ + buf[out++] = '\\'; + + switch (c) + { + case '\n': + buf[out++] = 'n'; + break; + case '\b': + buf[out++] = 'b'; + break; + case '\t': + buf[out++] = 't'; + break; + case '\f': + buf[out++] = 'f'; + break; + case '\r': + buf[out++] = 'r'; + break; + case '\033': + buf[out++] = 'e'; + break; + case '\007': + buf[out++] = 'a'; + break; + default: + { + buf[out++] = '0' + ((c >> 6) & 0x7); + buf[out++] = '0' + ((c >> 3) & 0x7); + buf[out++] = '0' + ((c >> 0) & 0x7); + break; + } + } + } + else + { + if (quoter != 0 && (c == '\\' || c == quoter)) + buf[out++] = '\\'; + buf[out++] = c; + } + + if (async_safe) + this->write_async_safe (buf, out); + else + this->write (buf, out); +} + void |