/* 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 "defs.h"
#include <ctype.h>
-#include "common/gdb_wait.h"
+#include "gdbsupport/gdb_wait.h"
#include "event-top.h"
#include "gdbthread.h"
#include "fnmatch.h"
#include <chrono>
-#include "gdb_usleep.h"
#include "interps.h"
#include "gdb_regex.h"
-#include "common/job-control.h"
-#include "common/selftest.h"
-#include "common/gdb_optional.h"
+#include "gdbsupport/job-control.h"
+#include "gdbsupport/selftest.h"
+#include "gdbsupport/gdb_optional.h"
#include "cp-support.h"
#include <algorithm>
-#include "common/pathstuff.h"
+#include "gdbsupport/pathstuff.h"
#include "cli/cli-style.h"
-#include "common/scope-exit.h"
+#include "gdbsupport/scope-exit.h"
+#include "gdbarch.h"
+#include "cli-out.h"
+#include "gdbsupport/gdb-safe-ctype.h"
void (*deprecated_error_begin_hook) (void);
/* Prototypes for local functions */
static void vfprintf_maybe_filtered (struct ui_file *, const char *,
- va_list, int) ATTRIBUTE_PRINTF (2, 0);
+ va_list, bool, bool)
+ ATTRIBUTE_PRINTF (2, 0);
static void fputs_maybe_filtered (const char *, struct ui_file *, int);
/* A flag indicating whether to timestamp debugging messages. */
-static int debug_timestamp = 0;
+static bool debug_timestamp = false;
-/* Nonzero means that strings with character values >0x7F should be printed
- as octal escapes. Zero means just print the value (e.g. it's an
+/* True means that strings with character values >0x7F should be printed
+ as octal escapes. False means just print the value (e.g. it's an
international character, and the terminal or window can cope.) */
-int sevenbit_strings = 0;
+bool sevenbit_strings = false;
static void
show_sevenbit_strings (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
const char *warning_pre_print = "\nwarning: ";
-int pagination_enabled = 1;
+bool pagination_enabled = true;
static void
show_pagination_enabled (struct ui_file *file, int from_tty,
struct cmd_list_element *c, const char *value)
}
\f
-/* Cleanup utilities.
-
- These are not defined in cleanups.c (nor declared in cleanups.h)
- because while they use the "cleanup API" they are not part of the
- "cleanup API". */
-
-/* This function is useful for cleanups.
- Do
-
- foo = xmalloc (...);
- old_chain = make_cleanup (free_current_contents, &foo);
-
- to arrange to free the object thus allocated. */
-
-void
-free_current_contents (void *ptr)
-{
- void **location = (void **) ptr;
-
- if (location == NULL)
- internal_error (__FILE__, __LINE__,
- _("free_current_contents: NULL pointer"));
- if (*location != NULL)
- {
- xfree (*location);
- *location = NULL;
- }
-}
-\f
/* Print a warning message. The first argument STRING is the warning
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
/* Don't allow infinite error/warning recursion. */
{
- static char msg[] = "Recursive internal problem.\n";
+ static const char msg[] = "Recursive internal problem.\n";
switch (dejavu)
{
abort_with_message (msg);
default:
dejavu = 3;
- /* Newer GLIBC versions put the warn_unused_result attribute
- on write, but this is one of those rare cases where
- ignoring the return value is correct. Casting to (void)
- does not fix this problem. This is the solution suggested
- at http://gcc.gnu.org/bugzilla/show_bug.cgi?id=25509. */
+ /* Newer GLIBC versions put the warn_unused_result attribute
+ on write, but this is one of those rare cases where
+ ignoring the return value is correct. Casting to (void)
+ 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);
}
}
if (!confirm || !filtered_printing_initialized ())
quit_p = 1;
else
- quit_p = query (_("%s\nQuit this debugging session? "),
+ quit_p = query (_("%s\nQuit this debugging session? "),
reason.c_str ());
}
else if (problem->should_quit == internal_problem_yes)
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)
{
set_doc = xstrprintf (_("Set whether GDB should quit "
- "when an %s is detected"),
+ "when an %s is detected."),
problem->name);
show_doc = xstrprintf (_("Show whether GDB will quit "
- "when an %s is detected"),
+ "when an %s is detected."),
problem->name);
add_setshow_enum_cmd ("quit", class_maintenance,
internal_problem_modes,
if (problem->user_settable_should_dump_core)
{
set_doc = xstrprintf (_("Set whether GDB should create a core "
- "file of GDB when %s is detected"),
+ "file of GDB when %s is detected."),
problem->name);
show_doc = xstrprintf (_("Show whether GDB will create a core "
- "file of GDB when %s is detected"),
+ "file of GDB when %s is detected."),
problem->name);
add_setshow_enum_cmd ("corefile", class_maintenance,
internal_problem_modes,
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. */
#else
if (job_control
/* If there is no terminal switching for this target, then we can't
- possibly get screwed by the lack of job control. */
+ possibly get screwed by the lack of job control. */
|| !target_supports_terminal_ours ())
throw_quit ("Quit");
else
quit ();
quit_handler ();
-
- if (deprecated_interactive_hook)
- deprecated_interactive_hook ();
}
\f
}
}
+/* 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. */
return orglen;
}
+/* See utils.h. */
+
+ULONGEST
+uinteger_pow (ULONGEST v1, LONGEST v2)
+{
+ if (v2 < 0)
+ {
+ if (v1 == 0)
+ error (_("Attempt to raise 0 to negative power."));
+ else
+ return 0;
+ }
+ else
+ {
+ /* The Russian Peasant's Algorithm. */
+ ULONGEST v;
+
+ v = 1;
+ for (;;)
+ {
+ if (v2 & 1L)
+ v *= v1;
+ v2 >>= 1;
+ if (v2 == 0)
+ return v;
+ v1 *= v1;
+ }
+ }
+}
+
void
print_spaces (int n, struct ui_file *file)
{
fprintf_filtered (stream, "%s", host_address_to_string (addr));
}
-/* See utils.h. */
-
-char *
-make_hex_string (const gdb_byte *data, size_t length)
-{
- char *result = (char *) xmalloc (length * 2 + 1);
- char *p;
- size_t i;
-
- p = result;
- for (i = 0; i < length; ++i)
- p += xsnprintf (p, 3, "%02x", data[i]);
- *p = '\0';
- return result;
-}
-
\f
/* An RAII class that sets up to handle input and then tears down
if (answer >= 'a')
answer -= 040;
/* Check answer. For the non-default, the user must specify
- the non-default explicitly. */
+ the non-default explicitly. */
if (answer == not_def_answer)
{
retval = !def_value;
break;
}
/* Otherwise, if a default was specified, the user may either
- specify the required input or have it default by entering
- nothing. */
+ specify the required input or have it default by entering
+ nothing. */
if (answer == def_answer
|| (defchar != '\0' && answer == '\0'))
{
while (++count < 3)
{
c = (**string_ptr);
- if (isdigit (c) && c != '8' && c != '9')
+ if (ISDIGIT (c) && c != '8' && c != '9')
{
(*string_ptr)++;
i *= 8;
chars_per_line = cols;
/* Readline should have fetched the termcap entry for us.
- Only try to use tgetnum function if rl_get_screen_size
- did not return a useful value. */
+ Only try to use tgetnum function if rl_get_screen_size
+ did not return a useful value. */
if (((rows <= 0) && (tgetnum ((char *) "li") < 0))
/* Also disable paging if inside Emacs. $EMACS was used
before Emacs v25.1, $INSIDE_EMACS is used since then. */
|| getenv ("EMACS") || getenv ("INSIDE_EMACS"))
{
/* The number of lines per page is not mentioned in the terminal
- description or EMACS evironment variable is set. This probably
+ description or EMACS environment variable is set. This probably
means that paging is not useful, so disable paging. */
lines_per_page = UINT_MAX;
}
/* 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
}
commands and either:
- the user specified "unlimited", which maps to UINT_MAX, or
- - the user spedified some number between INT_MAX and UINT_MAX.
+ - the user specified some number between INT_MAX and UINT_MAX.
Cap "infinity" to approximately sqrt(INT_MAX) so that we don't
overflow in rl_set_screen_size, which multiplies rows and columns
if (stream == nullptr)
wrap_buffer.append (style.to_ansi ());
else
- fputs_unfiltered (style.to_ansi ().c_str (), stream);
-}
-
-/* See utils.h. */
-
-bool
-can_emit_style_escape (struct ui_file *stream)
-{
- if (stream != gdb_stdout
- || !cli_styling
- || !ui_file_isatty (stream))
- return false;
- const char *term = getenv ("TERM");
- if (term == nullptr || !strcmp (term, "dumb"))
- return false;
- return true;
+ stream->puts (style.to_ansi ().c_str ());
}
/* Set the current output style. This will affect future uses of the
static void
set_output_style (struct ui_file *stream, const ui_file_style &style)
{
- if (!can_emit_style_escape (stream))
+ if (!stream->can_emit_style_escape ())
return;
- /* Note that we don't pass STREAM here, because we want to emit to
+ /* Note that we may not pass STREAM here, when we want to emit to
the wrap buffer, not directly to STREAM. */
- emit_style_escape (style);
+ if (stream == gdb_stdout)
+ stream = nullptr;
+ emit_style_escape (style, stream);
}
/* See utils.h. */
void
reset_terminal_style (struct ui_file *stream)
{
- if (can_emit_style_escape (stream))
+ if (stream->can_emit_style_escape ())
{
/* Force the setting, regardless of what we think the setting
might already be. */
bool disable_pagination = pagination_disabled_for_command;
/* Clear the current styling. */
- if (can_emit_style_escape (gdb_stdout))
+ if (gdb_stdout->can_emit_style_escape ())
emit_style_escape (ui_file_style (), gdb_stdout);
if (annotation_level > 1)
reinitialize_more_filter ();
pagination_disabled_for_command = disable_pagination;
- /* Restore the current styling. */
- if (can_emit_style_escape (gdb_stdout))
- emit_style_escape (applied_style);
-
dont_repeat (); /* Forget prev cmd -- CR won't repeat it. */
}
{
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;
}
{
wrap_buffer.push_back ('\t');
/* Shifting right by 3 produces the number of tab stops
- we have already passed, and then adding one and
- shifting left 3 advances to the next tab stop. */
+ we have already passed, and then adding one and
+ shifting left 3 advances to the next tab stop. */
chars_printed = ((chars_printed >> 3) + 1) << 3;
lineptr++;
}
{
unsigned int save_chars = chars_printed;
+ /* If we change the style, below, we'll want to reset it
+ before continuing to print. If there is no wrap
+ column, then we'll only reset the style if the pager
+ prompt is given; and to avoid emitting style
+ sequences in the middle of a run of text, we track
+ this as well. */
+ ui_file_style save_style;
+ bool did_paginate = false;
+
chars_printed = 0;
lines_printed++;
if (wrap_column)
{
- if (can_emit_style_escape (stream))
+ save_style = wrap_style;
+ if (stream->can_emit_style_escape ())
emit_style_escape (ui_file_style (), stream);
/* If we aren't actually wrapping, don't output
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
- flush_wrap_buffer (stream);
+ {
+ save_style = applied_style;
+ flush_wrap_buffer (stream);
+ }
/* Possible new page. Note that
PAGINATION_DISABLED_FOR_COMMAND might be set during
this loop, so we must continue to check it here. */
if (lines_printed >= lines_per_page - 1
&& !pagination_disabled_for_command)
- prompt_for_continue ();
+ {
+ prompt_for_continue ();
+ did_paginate = true;
+ }
/* Now output indentation and wrapped string. */
if (wrap_column)
{
- fputs_unfiltered (wrap_indent, stream);
- if (can_emit_style_escape (stream))
- emit_style_escape (wrap_style, 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
containing tabs. However, if we recurse to print it
and count its chars, we risk trouble if wrap_indent is
+ (save_chars - wrap_column);
wrap_column = 0; /* And disable fancy wrap */
}
+ else if (did_paginate && stream->can_emit_style_escape ())
+ emit_style_escape (save_style, stream);
}
}
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
}
}
+/* See utils.h. */
+
+void
+fputs_styled_unfiltered (const char *linebuffer, const ui_file_style &style,
+ struct ui_file *stream)
+{
+ /* This just makes it so we emit somewhat fewer escape
+ sequences. */
+ if (style.is_default ())
+ fputs_maybe_filtered (linebuffer, stream, 0);
+ else
+ {
+ set_output_style (stream, style);
+ fputs_maybe_filtered (linebuffer, stream, 0);
+ set_output_style (stream, ui_file_style ());
+ }
+}
+
+/* See utils.h. */
+
+void
+fputs_highlighted (const char *str, const compiled_regex &highlight,
+ struct ui_file *stream)
+{
+ regmatch_t pmatch;
+
+ while (*str && highlight.exec (str, 1, &pmatch, 0) == 0)
+ {
+ size_t n_highlight = pmatch.rm_eo - pmatch.rm_so;
+
+ /* Output the part before pmatch with current style. */
+ while (pmatch.rm_so > 0)
+ {
+ fputc_filtered (*str, stream);
+ pmatch.rm_so--;
+ str++;
+ }
+
+ /* Output pmatch with the highlight style. */
+ set_output_style (stream, highlight_style.style ());
+ while (n_highlight > 0)
+ {
+ fputc_filtered (*str, stream);
+ n_highlight--;
+ str++;
+ }
+ set_output_style (stream, ui_file_style ());
+ }
+
+ /* Output the trailing part of STR not matching HIGHLIGHT. */
+ if (*str)
+ fputs_filtered (str, stream);
+}
+
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
/* Print a variable number of ARGS using format FORMAT. If this
information is going to put the amount written (since the last call
to REINITIALIZE_MORE_FILTER or the last page break) over the page size,
- call prompt_for_continue to get the users permision to continue.
+ call prompt_for_continue to get the users permission to continue.
Unlike fprintf, this function does not return a value.
We implement three variants, vfprintf (takes a vararg list and stream),
fprintf (takes a stream to write on), and printf (the usual).
- Note also that a longjmp to top level may occur in this routine
- (since prompt_for_continue may do so) so this routine should not be
- called when cleanups are not in place. */
+ Note also that this may throw a quit (since prompt_for_continue may
+ do so). */
static void
vfprintf_maybe_filtered (struct ui_file *stream, const char *format,
- va_list args, int filter)
+ va_list args, bool filter, bool gdbfmt)
{
- std::string linebuffer = string_vprintf (format, args);
- fputs_maybe_filtered (linebuffer.c_str (), stream, filter);
+ if (gdbfmt)
+ {
+ ui_out_flags flags = disallow_ui_out_field;
+ if (!filter)
+ flags |= unfiltered_output;
+ cli_ui_out (stream, flags).vmessage (applied_style, format, args);
+ }
+ else
+ {
+ std::string str = string_vprintf (format, args);
+ fputs_maybe_filtered (str.c_str (), stream, filter);
+ }
}
void
vfprintf_filtered (struct ui_file *stream, const char *format, va_list args)
{
- vfprintf_maybe_filtered (stream, format, args, 1);
+ vfprintf_maybe_filtered (stream, format, args, true, true);
}
void
vfprintf_unfiltered (struct ui_file *stream, const char *format, va_list args)
{
- std::string linebuffer = string_vprintf (format, args);
if (debug_timestamp && stream == gdb_stdlog)
{
using namespace std::chrono;
int len, need_nl;
+ string_file sfile;
+ cli_ui_out (&sfile, 0).vmessage (ui_file_style (), format, args);
+ std::string linebuffer = std::move (sfile.string ());
+
steady_clock::time_point now = steady_clock::now ();
seconds s = duration_cast<seconds> (now.time_since_epoch ());
microseconds us = duration_cast<microseconds> (now.time_since_epoch () - s);
fputs_unfiltered (timestamp.c_str (), stream);
}
else
- fputs_unfiltered (linebuffer.c_str (), stream);
+ vfprintf_maybe_filtered (stream, format, args, false, true);
}
void
vprintf_filtered (const char *format, va_list args)
{
- vfprintf_maybe_filtered (gdb_stdout, format, args, 1);
+ vfprintf_maybe_filtered (gdb_stdout, format, args, true, false);
}
void
set_output_style (stream, ui_file_style ());
}
+/* See utils.h. */
+
+void
+vfprintf_styled (struct ui_file *stream, const ui_file_style &style,
+ const char *format, va_list args)
+{
+ set_output_style (stream, style);
+ vfprintf_filtered (stream, format, args);
+ set_output_style (stream, ui_file_style ());
+}
+
+/* See utils.h. */
+
+void
+vfprintf_styled_no_gdbfmt (struct ui_file *stream, const ui_file_style &style,
+ bool filter, const char *format, va_list args)
+{
+ std::string str = string_vprintf (format, args);
+ if (!str.empty ())
+ {
+ if (!style.is_default ())
+ set_output_style (stream, style);
+ fputs_maybe_filtered (str.c_str (), stream, filter);
+ if (!style.is_default ())
+ set_output_style (stream, ui_file_style ());
+ }
+}
void
printf_filtered (const char *format, ...)
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;
{
int match;
- if (template_string != (char *) NULL && string_to_compare != (char *) NULL
+ if (template_string != NULL && string_to_compare != NULL
&& strlen (string_to_compare) <= strlen (template_string))
match =
(startswith (template_string, string_to_compare));
}
\f
-void
-initialize_utils (void)
-{
- add_setshow_uinteger_cmd ("width", class_support, &chars_per_line, _("\
-Set number of characters where GDB should wrap lines of its output."), _("\
-Show number of characters where GDB should wrap lines of its output."), _("\
-This affects where GDB wraps its output to fit the screen width.\n\
-Setting this to \"unlimited\" or zero prevents GDB from wrapping its output."),
- set_width_command,
- show_chars_per_line,
- &setlist, &showlist);
-
- add_setshow_uinteger_cmd ("height", class_support, &lines_per_page, _("\
-Set number of lines in a page for GDB output pagination."), _("\
-Show number of lines in a page for GDB output pagination."), _("\
-This affects the number of lines after which GDB will pause\n\
-its output and ask you whether to continue.\n\
-Setting this to \"unlimited\" or zero causes GDB never pause during output."),
- set_height_command,
- show_lines_per_page,
- &setlist, &showlist);
-
- add_setshow_boolean_cmd ("pagination", class_support,
- &pagination_enabled, _("\
-Set state of GDB output pagination."), _("\
-Show state of GDB output pagination."), _("\
-When pagination is ON, GDB pauses at end of each screenful of\n\
-its output and asks you whether to continue.\n\
-Turning pagination off is an alternative to \"set height unlimited\"."),
- NULL,
- show_pagination_enabled,
- &setlist, &showlist);
-
- add_setshow_boolean_cmd ("sevenbit-strings", class_support,
- &sevenbit_strings, _("\
-Set printing of 8-bit characters in strings as \\nnn."), _("\
-Show printing of 8-bit characters in strings as \\nnn."), NULL,
- NULL,
- show_sevenbit_strings,
- &setprintlist, &showprintlist);
-
- add_setshow_boolean_cmd ("timestamp", class_maintenance,
- &debug_timestamp, _("\
-Set timestamping of debugging messages."), _("\
-Show timestamping of debugging messages."), _("\
-When set, debugging messages will be marked with seconds and microseconds."),
- NULL,
- show_debug_timestamp,
- &setdebuglist, &showdebuglist);
-}
-
/* See utils.h. */
CORE_ADDR
{
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);
gdb_realpath_check_trailer ("", "");
}
+/* Test the gdb_argv::as_array_view method. */
+
+static void
+gdb_argv_as_array_view_test ()
+{
+ {
+ gdb_argv argv;
+
+ gdb::array_view<char *> view = argv.as_array_view ();
+
+ SELF_CHECK (view.data () == nullptr);
+ SELF_CHECK (view.size () == 0);
+ }
+ {
+ gdb_argv argv ("une bonne 50");
+
+ gdb::array_view<char *> view = argv.as_array_view ();
+
+ SELF_CHECK (view.size () == 3);
+ SELF_CHECK (strcmp (view[0], "une") == 0);
+ SELF_CHECK (strcmp (view[1], "bonne") == 0);
+ SELF_CHECK (strcmp (view[2], "50") == 0);
+ }
+}
+
#endif /* GDB_SELF_TEST */
/* Allocation function for the libiberty hash table which uses an
{
char **argv = buildargv (s);
- if (s != NULL && argv == NULL)
- malloc_failure (0);
-
freeargv (m_argv);
m_argv = argv;
}
-int
-compare_positive_ints (const void *ap, const void *bp)
-{
- /* Because we know we're comparing two ints which are positive,
- there's no danger of overflow here. */
- return * (int *) ap - * (int *) bp;
-}
-
#define AMBIGUOUS_MESS1 ".\nMatching formats:"
#define AMBIGUOUS_MESS2 \
".\nUse \"set gnutarget format-name\" to specify the format."
return pid;
}
-/* Substitute all occurences of string FROM by string TO in *STRINGP. *STRINGP
+/* Substitute all occurrences of string FROM by string TO in *STRINGP. *STRINGP
must come from xrealloc-compatible allocator and it may be updated. FROM
needs to be delimited by IS_DIR_SEPARATOR or DIRNAME_SEPARATOR (or be
located at the start or end of *STRINGP. */
if ((s == string || IS_DIR_SEPARATOR (s[-1])
|| s[-1] == DIRNAME_SEPARATOR)
- && (s[from_len] == '\0' || IS_DIR_SEPARATOR (s[from_len])
+ && (s[from_len] == '\0' || IS_DIR_SEPARATOR (s[from_len])
|| s[from_len] == DIRNAME_SEPARATOR))
{
char *string_new;
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."), _("\
+Show number of characters where GDB should wrap lines of its output."), _("\
+This affects where GDB wraps its output to fit the screen width.\n\
+Setting this to \"unlimited\" or zero prevents GDB from wrapping its output."),
+ set_width_command,
+ show_chars_per_line,
+ &setlist, &showlist);
+
+ add_setshow_uinteger_cmd ("height", class_support, &lines_per_page, _("\
+Set number of lines in a page for GDB output pagination."), _("\
+Show number of lines in a page for GDB output pagination."), _("\
+This affects the number of lines after which GDB will pause\n\
+its output and ask you whether to continue.\n\
+Setting this to \"unlimited\" or zero causes GDB never pause during output."),
+ set_height_command,
+ show_lines_per_page,
+ &setlist, &showlist);
+
+ add_setshow_boolean_cmd ("pagination", class_support,
+ &pagination_enabled, _("\
+Set state of GDB output pagination."), _("\
+Show state of GDB output pagination."), _("\
+When pagination is ON, GDB pauses at end of each screenful of\n\
+its output and asks you whether to continue.\n\
+Turning pagination off is an alternative to \"set height unlimited\"."),
+ NULL,
+ show_pagination_enabled,
+ &setlist, &showlist);
+
+ add_setshow_boolean_cmd ("sevenbit-strings", class_support,
+ &sevenbit_strings, _("\
+Set printing of 8-bit characters in strings as \\nnn."), _("\
+Show printing of 8-bit characters in strings as \\nnn."), NULL,
+ NULL,
+ show_sevenbit_strings,
+ &setprintlist, &showprintlist);
+
+ add_setshow_boolean_cmd ("timestamp", class_maintenance,
+ &debug_timestamp, _("\
+Set timestamping of debugging messages."), _("\
+Show timestamping of debugging messages."), _("\
+When set, debugging messages will be marked with seconds and microseconds."),
+ NULL,
+ show_debug_timestamp,
+ &setdebuglist, &showdebuglist);
+
add_internal_problem_command (&internal_error_problem);
add_internal_problem_command (&internal_warning_problem);
add_internal_problem_command (&demangler_warning_problem);
#if GDB_SELF_TEST
selftests::register_test ("gdb_realpath", gdb_realpath_tests);
+ selftests::register_test ("gdb_argv_array_view", gdb_argv_as_array_view_test);
#endif
}