do_close_cleanup (void *arg)
{
int *fd = arg;
+
close (*fd);
}
make_cleanup_close (int fd)
{
int *saved_fd = xmalloc (sizeof (fd));
+
*saved_fd = fd;
return make_cleanup_dtor (do_close_cleanup, saved_fd, xfree);
}
do_fclose_cleanup (void *arg)
{
FILE *file = arg;
- fclose (arg);
+
+ fclose (file);
}
/* Return a new cleanup that closes FILE. */
do_obstack_free (void *arg)
{
struct obstack *ob = arg;
+
obstack_free (ob, NULL);
}
restore_integer (void *p)
{
struct restore_integer_closure *closure = p;
+
*(closure->variable) = closure->value;
}
{
struct restore_integer_closure *c =
xmalloc (sizeof (struct restore_integer_closure));
+
c->variable = variable;
c->value = *variable;
struct cleanup *old_chain)
{
struct cleanup *ptr;
+
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next; /* Do this first incase recursion */
struct cleanup *old_chain)
{
struct cleanup *ptr;
+
while ((ptr = *pmy_chain) != old_chain)
{
*pmy_chain = ptr->next;
free_current_contents (void *ptr)
{
void **location = ptr;
+
if (location == NULL)
internal_error (__FILE__, __LINE__,
_("free_current_contents: NULL pointer"));
{
}
+/* If nonzero, display time usage both at startup and for each command. */
+
+static int display_time;
+
+/* If nonzero, display space usage both at startup and for each command. */
+
+static int display_space;
+
+/* Records a run time and space usage to be used as a base for
+ reporting elapsed time or change in space. In addition,
+ the msg_type field indicates whether the saved time is from the
+ beginning of GDB execution (0) or the beginning of an individual
+ command execution (1). */
+struct cmd_stats
+{
+ int msg_type;
+ long start_time;
+ long start_space;
+};
+
+/* Set whether to display time statistics to NEW_VALUE (non-zero
+ means true). */
+void
+set_display_time (int new_value)
+{
+ display_time = new_value;
+}
+
+/* Set whether to display space statistics to NEW_VALUE (non-zero
+ means true). */
+void
+set_display_space (int new_value)
+{
+ display_space = new_value;
+}
+
+/* As indicated by display_time and display_space, report GDB's elapsed time
+ and space usage from the base time and space provided in ARG, which
+ must be a pointer to a struct cmd_stat. This function is intended
+ to be called as a cleanup. */
+static void
+report_command_stats (void *arg)
+{
+ struct cmd_stats *start_stats = (struct cmd_stats *) arg;
+ int msg_type = start_stats->msg_type;
+
+ if (display_time)
+ {
+ long cmd_time = get_run_time () - start_stats->start_time;
+
+ printf_unfiltered (msg_type == 0
+ ? _("Startup time: %ld.%06ld\n")
+ : _("Command execution time: %ld.%06ld\n"),
+ cmd_time / 1000000, cmd_time % 1000000);
+ }
+
+ if (display_space)
+ {
+#ifdef HAVE_SBRK
+ char *lim = (char *) sbrk (0);
+
+ long space_now = lim - lim_at_start;
+ long space_diff = space_now - start_stats->start_space;
+
+ printf_unfiltered (msg_type == 0
+ ? _("Space used: %ld (%c%ld during startup)\n")
+ : _("Space used: %ld (%c%ld for this command)\n"),
+ space_now,
+ (space_diff >= 0 ? '+' : '-'),
+ space_diff);
+#endif
+ }
+}
+
+/* Create a cleanup that reports time and space used since its
+ creation. Precise messages depend on MSG_TYPE:
+ 0: Initial time/space
+ 1: Individual command time/space. */
+struct cleanup *
+make_command_stats_cleanup (int msg_type)
+{
+ struct cmd_stats *new_stat = XMALLOC (struct cmd_stats);
+
+#ifdef HAVE_SBRK
+ char *lim = (char *) sbrk (0);
+ new_stat->start_space = lim - lim_at_start;
+#endif
+
+ new_stat->msg_type = msg_type;
+ new_stat->start_time = get_run_time ();
+
+ return make_cleanup_dtor (report_command_stats, new_stat, xfree);
+}
+
/* Continuations are implemented as cleanups internally. Inherit from
cleanups. */
struct continuation
void
do_all_inferior_continuations (void)
{
- struct cleanup *old_chain;
struct cleanup *as_cleanup;
struct inferior *inf = current_inferior ();
discard_all_inferior_continuations (struct inferior *inf)
{
struct cleanup *continuation_ptr = &inf->continuations->base;
+
discard_my_cleanups (&continuation_ptr, NULL);
inf->continuations = NULL;
}
restore_thread_cleanup (void *arg)
{
ptid_t *ptid_p = arg;
+
switch_to_thread (*ptid_p);
}
void *data)
{
struct cleanup *continuation_ptr = &thread->continuations->base;
+
discard_my_cleanups (&continuation_ptr, NULL);
thread->continuations = NULL;
return 0;
void *data)
{
struct cleanup *continuation_ptr = &thread->intermediate_continuations->base;
+
discard_my_cleanups (&continuation_ptr, NULL);
thread->intermediate_continuations = NULL;
return 0;
warning (const char *string, ...)
{
va_list args;
+
va_start (args, string);
vwarning (string, args);
va_end (args);
error (const char *string, ...)
{
va_list args;
+
va_start (args, string);
throw_verror (GENERIC_ERROR, string, args);
va_end (args);
fatal (const char *string, ...)
{
va_list args;
+
va_start (args, string);
throw_vfatal (string, args);
va_end (args);
error_stream (struct ui_file *stream)
{
char *message = ui_file_xstrdup (stream, NULL);
+
make_cleanup (xfree, message);
error (("%s"), message);
}
internal_problem_no,
NULL
};
-static const char *internal_problem_mode = internal_problem_ask;
/* Print a message reporting an internal error/warning. Ask the user
if they want to continue, dump core, or just exit. Return
/* Don't allow infinite error/warning recursion. */
{
static char msg[] = "Recursive internal problem.\n";
+
switch (dejavu)
{
case 0:
so that the user knows that they are living on the edge. */
{
char *msg;
+
msg = xstrvprintf (fmt, ap);
reason = xstrprintf ("\
%s:%d: %s: %s\n\
internal_error (const char *file, int line, const char *string, ...)
{
va_list ap;
+
va_start (ap, string);
internal_verror (file, line, string, ap);
va_end (ap);
internal_warning (const char *file, int line, const char *string, ...)
{
va_list ap;
+
va_start (ap, string);
internal_vwarning (file, line, string, ap);
va_end (ap);
add_prefix_cmd ((char*) problem->name,
class_maintenance, set_internal_problem_cmd, set_doc,
set_cmd_list,
- concat ("maintenance set ", problem->name, " ", NULL),
+ concat ("maintenance set ", problem->name, " ",
+ (char *) NULL),
0/*allow-unknown*/, &maintenance_set_cmdlist);
add_prefix_cmd ((char*) problem->name,
class_maintenance, show_internal_problem_cmd, show_doc,
show_cmd_list,
- concat ("maintenance show ", problem->name, " ", NULL),
+ concat ("maintenance show ", problem->name, " ",
+ (char *) NULL),
0/*allow-unknown*/, &maintenance_show_cmdlist);
set_doc = xstrprintf (_("\
{
char *ret;
va_list args;
+
va_start (args, format);
ret = xstrvprintf (format, args);
va_end (args);
xasprintf (char **ret, const char *format, ...)
{
va_list args;
+
va_start (args, format);
(*ret) = xstrvprintf (format, args);
va_end (args);
{
char *ret = NULL;
int status = vasprintf (&ret, format, ap);
+
/* NULL is returned when there was a memory allocation problem, or
any other error (for instance, a bad format string). A negative
status (the printed length) with a non-NULL buffer should never
savestring (const char *ptr, size_t size)
{
char *p = (char *) xmalloc (size + 1);
+
memcpy (p, ptr, size);
p[size] = 0;
return p;
{
int target_char = -2; /* initialize to avoid GCC warnings */
int c = *(*string_ptr)++;
+
switch (c)
{
case '\n':
void (*do_fprintf) (struct ui_file *, const char *, ...)
ATTRIBUTE_FPTR_PRINTF_2, struct ui_file *stream, int quoter)
{
-
c &= 0xFF; /* Avoid sign bit follies */
if (c < 0x20 || /* Low control chars */
struct ui_file *stream)
{
int i;
+
for (i = 0; i < n; i++)
printchar (str[i], fputs_filtered, fprintf_filtered, stream, quoter);
}
struct ui_file *stream)
{
int i;
+
for (i = 0; i < n; i++)
printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter);
}
if (ignore)
{
char *p = ignore;
+
while (*p == ' ' || *p == '\t')
++p;
if (p[0] == 'q')
putchar_unfiltered (int c)
{
char buf = c;
+
ui_file_write (gdb_stdout, &buf, 1);
return c;
}
fputc_unfiltered (int c, struct ui_file *stream)
{
char buf = c;
+
ui_file_write (stream, &buf, 1);
return c;
}
fprintf_filtered (struct ui_file *stream, const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_filtered (stream, format, args);
va_end (args);
fprintf_unfiltered (struct ui_file *stream, const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_unfiltered (stream, format, args);
va_end (args);
...)
{
va_list args;
+
va_start (args, format);
print_spaces_filtered (spaces, stream);
printf_filtered (const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_filtered (gdb_stdout, format, args);
va_end (args);
printf_unfiltered (const char *format, ...)
{
va_list args;
+
va_start (args, format);
vfprintf_unfiltered (gdb_stdout, format, args);
va_end (args);
printfi_filtered (int spaces, const char *format, ...)
{
va_list args;
+
va_start (args, format);
print_spaces_filtered (spaces, gdb_stdout);
vfprintf_filtered (gdb_stdout, format, args);
subset_compare (char *string_to_compare, char *template_string)
{
int match;
+
if (template_string != (char *) NULL && string_to_compare != (char *) NULL
&& strlen (string_to_compare) <= strlen (template_string))
match =
void
initialize_utils (void)
{
- struct cmd_list_element *c;
-
add_setshow_uinteger_cmd ("width", class_support, &chars_per_line, _("\
Set number of characters gdb thinks are in a line."), _("\
Show number of characters gdb thinks are in a line."), NULL,
{
static char buf[NUMCELLS][CELLSIZE];
static int cell = 0;
+
if (++cell >= NUMCELLS)
cell = 0;
return buf[cell];
about the real size of addr as the above does? */
unsigned long temp[3];
char *str = get_cell ();
-
int i = 0;
+
do
{
temp[i] = addr % (1000 * 1000 * 1000);
{
unsigned long temp[3];
char *str = get_cell ();
-
int i = 0;
+
do
{
temp[i] = addr % (0100000 * 0100000);
case 8:
{
unsigned long high = (unsigned long) (l >> thirty_two);
+
str = get_cell ();
if (high == 0)
xsnprintf (str, CELLSIZE, "%lx",
hex_string (LONGEST num)
{
char *result = get_cell ();
+
xsnprintf (result, CELLSIZE, "0x%s", phex_nz (num, sizeof (num)));
return result;
}
case 16:
{
char *result;
+
if (width == 0)
result = hex_string (val);
else
case 8:
{
char *result = octal2str (val, width);
+
if (use_c_format || val == 0)
return result;
else
core_addr_to_string (const CORE_ADDR addr)
{
char *str = get_cell ();
+
strcpy (str, "0x");
strcat (str, phex (addr, sizeof (addr)));
return str;
core_addr_to_string_nz (const CORE_ADDR addr)
{
char *str = get_cell ();
+
strcpy (str, "0x");
strcat (str, phex_nz (addr, sizeof (addr)));
return str;
{
/* Assume that it is in hex. */
int i;
+
for (i = 2; my_string[i] != '\0'; i++)
{
if (isdigit (my_string[i]))
{
/* Assume that it is in decimal. */
int i;
+
for (i = 0; my_string[i] != '\0'; i++)
{
if (isdigit (my_string[i]))
# endif
# if defined (USE_REALPATH)
const char *rp = realpath (filename, buf);
+
if (rp == NULL)
rp = filename;
return xstrdup (rp);
#if defined(HAVE_CANONICALIZE_FILE_NAME)
{
char *rp = canonicalize_file_name (filename);
+
if (rp == NULL)
return xstrdup (filename);
else
{
/* Find out the max path size. */
long path_max = pathconf ("/", _PC_PATH_MAX);
+
if (path_max > 0)
{
/* PATH_MAX is bounded. */
char *buf = alloca (path_max);
char *rp = realpath (filename, buf);
+
return xstrdup (rp ? rp : filename);
}
}
directory separator, avoid doubling it. */
real_path = gdb_realpath (dir_name);
if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1]))
- result = concat (real_path, base_name, (char *)NULL);
+ result = concat (real_path, base_name, (char *) NULL);
else
- result = concat (real_path, SLASH_STRING, base_name, (char *)NULL);
+ result = concat (real_path, SLASH_STRING, base_name, (char *) NULL);
xfree (real_path);
return result;
{
unsigned int total = size * count;
void *ptr = obstack_alloc ((struct obstack *) data, total);
+
memset (ptr, 0, total);
return ptr;
}
gdb_buildargv (const char *s)
{
char **argv = buildargv (s);
+
if (s != NULL && argv == NULL)
nomem (0);
return argv;