/* General utility routines for GDB, the GNU debugger.
- Copyright (C) 1986-2019 Free Software Foundation, Inc.
+ Copyright (C) 1986-2020 Free Software Foundation, Inc.
This file is part of GDB.
#include "gdbsupport/scope-exit.h"
#include "gdbarch.h"
#include "cli-out.h"
+#include "gdbsupport/gdb-safe-ctype.h"
void (*deprecated_error_begin_hook) (void);
else
fputs_unfiltered (msg, gdb_stderr);
- abort (); /* NOTE: GDB has only three calls to abort(). */
+ abort (); /* ARI: abort */
}
/* Dump core trying to increase the core soft limit to hard limit first. */
setrlimit (RLIMIT_CORE, &rlim);
#endif /* HAVE_SETRLIMIT */
- abort (); /* NOTE: GDB has only three calls to abort(). */
+ abort (); /* ARI: abort */
}
/* Check whether GDB will be able to dump core using the dump_core
does not fix this problem. This is the solution suggested
at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509. */
if (write (STDERR_FILENO, msg, sizeof (msg)) != sizeof (msg))
- abort (); /* NOTE: GDB has only three calls to abort(). */
+ abort (); /* ARI: abort */
exit (1);
}
}
va_end (ap);
}
-/* Dummy functions to keep add_prefix_cmd happy. */
-
-static void
-set_internal_problem_cmd (const char *args, int from_tty)
-{
-}
-
-static void
-show_internal_problem_cmd (const char *args, int from_tty)
-{
-}
-
/* When GDB reports an internal problem (error or warning) it gives
the user the opportunity to quit GDB and/or create a core file of
the current debug session. This function registers a few commands
show_doc = xstrprintf (_("Show what GDB does when %s is detected."),
problem->name);
- add_prefix_cmd (problem->name,
- class_maintenance, set_internal_problem_cmd, set_doc,
- set_cmd_list,
- concat ("maintenance set ", problem->name, " ",
- (char *) NULL),
- 0/*allow-unknown*/, &maintenance_set_cmdlist);
+ add_basic_prefix_cmd (problem->name, class_maintenance, set_doc,
+ set_cmd_list,
+ concat ("maintenance set ", problem->name, " ",
+ (char *) NULL),
+ 0/*allow-unknown*/, &maintenance_set_cmdlist);
- add_prefix_cmd (problem->name,
- class_maintenance, show_internal_problem_cmd, show_doc,
- show_cmd_list,
- concat ("maintenance show ", problem->name, " ",
- (char *) NULL),
- 0/*allow-unknown*/, &maintenance_show_cmdlist);
+ add_show_prefix_cmd (problem->name, class_maintenance, show_doc,
+ show_cmd_list,
+ concat ("maintenance show ", problem->name, " ",
+ (char *) NULL),
+ 0/*allow-unknown*/, &maintenance_show_cmdlist);
if (problem->user_settable_should_quit)
{
static std::string
perror_string (const char *prefix)
{
- char *err;
-
- err = safe_strerror (errno);
+ const char *err = safe_strerror (errno);
return std::string (prefix) + ": " + err;
}
void
print_sys_errmsg (const char *string, int errcode)
{
- char *err;
- char *combined;
-
- err = safe_strerror (errcode);
- combined = (char *) alloca (strlen (err) + strlen (string) + 3);
- strcpy (combined, string);
- strcat (combined, ": ");
- strcat (combined, err);
-
+ const char *err = safe_strerror (errcode);
/* We want anything which was printed on stdout to come out first, before
this message. */
gdb_flush (gdb_stdout);
- fprintf_unfiltered (gdb_stderr, "%s.\n", combined);
+ fprintf_unfiltered (gdb_stderr, "%s: %s.\n", string, err);
}
/* Control C eventually causes this to be called, at a convenient time. */
}
}
+/* See common/errors.h. */
+
+void
+flush_streams ()
+{
+ gdb_stdout->flush ();
+ gdb_stderr->flush ();
+}
+
/* My replacement for the read system call.
Used like `read' but keeps going if `read' returns too soon. */
while (++count < 3)
{
c = (**string_ptr);
- if (isdigit (c) && c != '8' && c != '9')
+ if (ISDIGIT (c) && c != '8' && c != '9')
{
(*string_ptr)++;
i *= 8;
}
/* If the output is not a terminal, don't paginate it. */
- if (!ui_file_isatty (gdb_stdout))
+ if (!gdb_stdout->isatty ())
lines_per_page = UINT_MAX;
#endif
}
if (stream == nullptr)
wrap_buffer.append (style.to_ansi ());
else
- fputs_unfiltered (style.to_ansi ().c_str (), stream);
+ stream->puts (style.to_ansi ().c_str ());
}
/* Set the current output style. This will affect future uses of the
{
if (stream == gdb_stdout && !wrap_buffer.empty ())
{
- fputs_unfiltered (wrap_buffer.c_str (), stream);
+ stream->puts (wrap_buffer.c_str ());
wrap_buffer.clear ();
}
}
+/* See utils.h. */
+
+void
+gdb_flush (struct ui_file *stream)
+{
+ flush_wrap_buffer (stream);
+ stream->flush ();
+}
+
/* Indicate that if the next sequence of characters overflows the line,
a newline should be inserted here rather than when it hits the end.
If INDENT is non-null, it is a string to be printed to indent the
wrap_here (const char *indent)
{
/* This should have been allocated, but be paranoid anyway. */
- if (!filter_initialized)
- internal_error (__FILE__, __LINE__,
- _("failed internal consistency check"));
+ gdb_assert (filter_initialized);
flush_wrap_buffer (gdb_stdout);
if (chars_per_line == UINT_MAX) /* No line overflow checking. */
|| top_level_interpreter ()->interp_ui_out ()->is_mi_like_p ())
{
flush_wrap_buffer (stream);
- fputs_unfiltered (linebuffer, stream);
+ stream->puts (linebuffer);
return;
}
newline -- if chars_per_line is right, we
probably just overflowed anyway; if it's wrong,
let us keep going. */
- fputc_unfiltered ('\n', stream);
+ /* XXX: The ideal thing would be to call
+ 'stream->putc' here, but we can't because it
+ currently calls 'fputc_unfiltered', which ends up
+ calling us, which generates an infinite
+ recursion. */
+ stream->puts ("\n");
}
else
{
/* Now output indentation and wrapped string. */
if (wrap_column)
{
- fputs_unfiltered (wrap_indent, stream);
+ stream->puts (wrap_indent);
if (stream->can_emit_style_escape ())
emit_style_escape (save_style, stream);
/* FIXME, this strlen is what prevents wrap_indent from
wrap_here ((char *) 0); /* Spit out chars, cancel
further wraps. */
lines_printed++;
- fputc_unfiltered ('\n', stream);
+ /* XXX: The ideal thing would be to call
+ 'stream->putc' here, but we can't because it
+ currently calls 'fputc_unfiltered', which ends up
+ calling us, which generates an infinite
+ recursion. */
+ stream->puts ("\n");
lineptr++;
}
}
fputs_maybe_filtered (linebuffer, stream, 1);
}
+void
+fputs_unfiltered (const char *linebuffer, struct ui_file *stream)
+{
+ fputs_maybe_filtered (linebuffer, stream, 0);
+}
+
/* See utils.h. */
void
int
putchar_unfiltered (int c)
{
- char buf = c;
-
- ui_file_write (gdb_stdout, &buf, 1);
- return c;
+ return fputc_unfiltered (c, gdb_stdout);
}
/* Write character C to gdb_stdout using GDB's paging mechanism and return C.
int
fputc_unfiltered (int c, struct ui_file *stream)
{
- char buf = c;
+ char buf[2];
- ui_file_write (stream, &buf, 1);
+ buf[0] = c;
+ buf[1] = 0;
+ fputs_unfiltered (buf, stream);
return c;
}
switch (ch)
{
default:
- if (isprint (ch))
+ if (gdb_isprint (ch))
fputc_unfiltered (ch, gdb_stdlog);
else
if (n > max_spaces)
{
- if (spaces)
- xfree (spaces);
+ xfree (spaces);
spaces = (char *) xmalloc (n + 1);
for (t = spaces + n; t != spaces;)
*--t = ' ';
static bool
valid_identifier_name_char (int ch)
{
- return (isalnum (ch) || ch == '_');
+ return (ISALNUM (ch) || ch == '_');
}
/* Skip to end of token, or to END, whatever comes first. Input is
cp_skip_operator_token (const char *token, const char *end)
{
const char *p = token;
- while (p != end && !isspace (*p) && *p != '(')
+ while (p != end && !ISSPACE (*p) && *p != '(')
{
if (valid_identifier_name_char (*p))
{
static void
skip_ws (const char *&string1, const char *&string2, const char *end_str2)
{
- while (isspace (*string1))
+ while (ISSPACE (*string1))
string1++;
- while (string2 < end_str2 && isspace (*string2))
+ while (string2 < end_str2 && ISSPACE (*string2))
string2++;
}
while (1)
{
if (skip_spaces
- || ((isspace (*string1) && !valid_identifier_name_char (*string2))
- || (isspace (*string2) && !valid_identifier_name_char (*string1))))
+ || ((ISSPACE (*string1) && !valid_identifier_name_char (*string2))
+ || (ISSPACE (*string2) && !valid_identifier_name_char (*string1))))
{
skip_ws (string1, string2, end_str2);
skip_spaces = false;
if (match_for_lcd != NULL && abi_start != string1)
match_for_lcd->mark_ignored_range (abi_start, string1);
- while (isspace (*string1))
+ while (ISSPACE (*string1))
string1++;
}
string1++;
string2++;
- while (isspace (*string1))
+ while (ISSPACE (*string1))
string1++;
- while (string2 < end_str2 && isspace (*string2))
+ while (string2 < end_str2 && ISSPACE (*string2))
string2++;
continue;
}
if (case_sensitivity == case_sensitive_on && *string1 != *string2)
break;
if (case_sensitivity == case_sensitive_off
- && (tolower ((unsigned char) *string1)
- != tolower ((unsigned char) *string2)))
+ && (TOLOWER ((unsigned char) *string1)
+ != TOLOWER ((unsigned char) *string2)))
break;
/* If we see any non-whitespace, non-identifier-name character
(any of "()<>*&" etc.), then skip spaces the next time
around. */
- if (!isspace (*string1) && !valid_identifier_name_char (*string1))
+ if (!ISSPACE (*string1) && !valid_identifier_name_char (*string1))
skip_spaces = true;
string1++;
while (*string1 != '\0' && *string2 != '\0')
{
- while (isspace (*string1))
+ while (ISSPACE (*string1))
string1++;
- while (isspace (*string2))
+ while (ISSPACE (*string2))
string2++;
switch (case_pass)
{
case case_sensitive_off:
- c1 = tolower ((unsigned char) *string1);
- c2 = tolower ((unsigned char) *string2);
+ c1 = TOLOWER ((unsigned char) *string1);
+ c2 = TOLOWER ((unsigned char) *string2);
break;
case case_sensitive_on:
c1 = *string1;
{
CORE_ADDR addr = 0;
- if (my_string[0] == '0' && tolower (my_string[1]) == 'x')
+ if (my_string[0] == '0' && TOLOWER (my_string[1]) == 'x')
{
/* Assume that it is in hex. */
int i;
for (i = 2; my_string[i] != '\0'; i++)
{
- if (isdigit (my_string[i]))
+ if (ISDIGIT (my_string[i]))
addr = (my_string[i] - '0') + (addr * 16);
- else if (isxdigit (my_string[i]))
- addr = (tolower (my_string[i]) - 'a' + 0xa) + (addr * 16);
+ else if (ISXDIGIT (my_string[i]))
+ addr = (TOLOWER (my_string[i]) - 'a' + 0xa) + (addr * 16);
else
error (_("invalid hex \"%s\""), my_string);
}
for (i = 0; my_string[i] != '\0'; i++)
{
- if (isdigit (my_string[i]))
+ if (ISDIGIT (my_string[i]))
addr = (my_string[i] - '0') + (addr * 10);
else
error (_("invalid decimal \"%s\""), my_string);
{
char **argv = buildargv (s);
- if (s != NULL && argv == NULL)
- malloc_failure (0);
-
freeargv (m_argv);
m_argv = argv;
}
buf |= *source << avail;
buf &= (1 << nbits) - 1;
- *dest = (*dest & (~0 << nbits)) | buf;
+ *dest = (*dest & (~0U << nbits)) | buf;
}
}
+void _initialize_utils ();
void
-_initialize_utils (void)
+_initialize_utils ()
{
add_setshow_uinteger_cmd ("width", class_support, &chars_per_line, _("\
Set number of characters where GDB should wrap lines of its output."), _("\