aboutsummaryrefslogtreecommitdiff
path: root/gdb/ui-file.c
diff options
context:
space:
mode:
authorTom Tromey <tom@tromey.com>2021-12-31 10:40:02 -0700
committerTom Tromey <tom@tromey.com>2022-01-05 11:01:02 -0700
commitd53fd721a18f8c827aa69ffbd15abd99641b5e20 (patch)
tree436641845129a7eb9eb38733a456656da9312366 /gdb/ui-file.c
parent28a4e64dd1b17b0d9f267c3466d7da3e8a41afd8 (diff)
downloadgdb-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.c69
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