Files
mercury/trace/mercury_trace_alias.c
Julien Fischer 4bf295460a Fix up some places in the trace directory where there were (potential)
Estimated hours taken: 5
Branches: main

Fix up some places in the trace directory where there were (potential)
mismatches between the sizes of types used to represent natural numbers.
Much of the existing code in the trace directory assumed that
sizeof(int) == sizeof(MR_Unsigned), which is not true on our 64-bit
machines.  Zoltan's recent change to MR_trace_is_natural_number() broke
that assumption in a lot of places.  (I committed a workaround for that
yesterday.)

This diff addresses the above problem by changing the types of many of
things that represent natural numbers from int to MR_Unsigned.
This should make the trace code more robust on 64-bit machines and
help avoid a recurrence of problems like the above.

NOTE: this change does not change slot numbers into unsigned values since
they still use negative values as sentinels.  I will address slot numbers
in as part of a separate change.

trace/mercury_trace.h:
	Add typedefs for MR_Unsigned for several commonly used quantities
	within the trace code.  For I/O action numbers we just re-use
	the type MR_IoActionNum from the runtime, rather than defining
	a new typedef here.

trace/mercury_trace_tables.h:
	Change the type of the `match_proc_max' and `match_proc_next' fields
	of the MR_MatchesInfo structure into MR_Unsigned instead of int.

trace/mercury_trace_cmd_parameter.[ch]:
	Change the type of the global variables, MR_scroll_{limit,next}
	and MR_num_context_lines into MR_Unsigned instead of int.

trace/mercury_trace_util.[ch]:
	Restore Zoltan's change that made the type of the second argument of
	MR_trace_is_natural_number() into MR_Unsigned.  The places that
	caused this to break on 64-bit machines have now been fixed.

	Update the documentation of MR_trace_is_natural_number();

	Delete MR_trace_is_unsigned() since that now duplicates
	MR_trace_is_natural_number().

	Add a new function MR_trace_is_nonneg_int() which is similar
	to the above functions except that it stores its result in
	an int.  (This is needed for handling slot numbers which are
	still represented using ints.)

trace/mercury_trace_cmd_developer.c:
	Refactor some code so that we don't need to use -1 as a sentinel
	value.

trace/mercury_trace_cmd_help.c:
	Use MR_trace_is_nonneg_int() instead of MR_trace_is_natural_number()
	to handle slot numbers.

runtime/mercury_trace_base.[ch]:
	Change the type of the first argument of MR_trace_get_action()
	from int to MR_IoActionNum.

trace/mercury_trace_alias.c:
trace/mercury_trace_cmd_backward.c:
trace/mercury_trace_cmd_breakpoint.c:
trace/mercury_trace_cmd_browsing.c:
trace/mercury_trace_cmd_dd.c:
trace/mercury_trace_cmd_exp.c:
trace/mercury_trace_cmd_forward.c:
trace/mercury_stack_trace.c:
trace/mercury_trace_internal.c:
trace/mercury_trace_spy.[ch]:
trace/mercury_trace_vars.[ch]:
	Use MR_Unsigned instead of int to represent natural numbers.
2007-10-02 03:37:29 +00:00

226 lines
6.2 KiB
C

/*
** vim: ts=4 sw=4 expandtab
*/
/*
** Copyright (C) 1998-2000,2002-2003, 2005-2007 The University of Melbourne.
** This file may only be copied under the terms of the GNU Library General
** Public License - see the file COPYING.LIB in the Mercury distribution.
*/
/*
** mercury_trace_alias.c - implements the table of aliases for the
** internal debugger.
**
** Author: zs.
*/
#include "mercury_imp.h"
#include "mercury_array_macros.h"
#include "mercury_trace_alias.h"
#include "mercury_trace_util.h"
static MR_Alias *MR_alias_records = NULL;
static int MR_alias_record_max = 0;
static int MR_alias_record_next = 0;
/* The initial size of arrays of words. */
#define MR_INIT_WORD_COUNT 20
/* The initial size of the alias table. */
#define INIT_ALIAS_COUNT 32
static void MR_trace_print_alias_num(FILE *fp, int slot,
MR_bool mdb_command_format);
static char *MR_trace_get_alias_slot_name(int slot);
static MR_bool MR_trace_filter_alias_completions(const char *word,
MR_CompleterData *data);
void
MR_trace_add_alias(char *name, char **words, int word_count)
{
MR_bool found;
int slot;
int i;
int count;
MR_bsearch(MR_alias_record_next, slot, found,
strcmp(MR_alias_records[slot].MR_alias_name, name));
if (found) {
count = MR_alias_records[slot].MR_alias_word_count;
for (i = 0; i < count; i++) {
MR_free(MR_alias_records[slot].MR_alias_words[i]);
}
MR_free(MR_alias_records[slot].MR_alias_name);
MR_free(MR_alias_records[slot].MR_alias_words);
} else {
MR_ensure_room_for_next(MR_alias_record, MR_Alias, INIT_ALIAS_COUNT);
MR_prepare_insert_into_sorted(MR_alias_records, MR_alias_record_next,
slot, strcmp(MR_alias_records[slot].MR_alias_name, name));
}
MR_alias_records[slot].MR_alias_name = MR_copy_string(name);
MR_alias_records[slot].MR_alias_word_count = word_count;
MR_alias_records[slot].MR_alias_words = MR_NEW_ARRAY(char *, word_count);
for (i = 0; i < word_count; i++) {
MR_alias_records[slot].MR_alias_words[i] = MR_copy_string(words[i]);
}
}
MR_bool
MR_trace_remove_alias(const char *name)
{
MR_bool found;
int slot;
int i;
int count;
MR_bsearch(MR_alias_record_next, slot, found,
strcmp(MR_alias_records[slot].MR_alias_name, name));
if (! found) {
return MR_FALSE;
} else {
count = MR_alias_records[slot].MR_alias_word_count;
for (i = 0; i < count; i++) {
MR_free(MR_alias_records[slot].MR_alias_words[i]);
}
MR_free(MR_alias_records[slot].MR_alias_name);
MR_free(MR_alias_records[slot].MR_alias_words);
for (i = slot; i < MR_alias_record_next - 1; i++) {
MR_assign_structure(MR_alias_records[slot],
MR_alias_records[slot + 1]);
}
MR_alias_record_next--;
return MR_TRUE;
}
}
MR_bool
MR_trace_lookup_alias(const char *name,
char ***words_ptr, int *word_count_ptr)
{
MR_bool found;
int slot;
MR_bsearch(MR_alias_record_next, slot, found,
strcmp(MR_alias_records[slot].MR_alias_name, name));
if (found) {
*word_count_ptr = MR_alias_records[slot].MR_alias_word_count;
*words_ptr = MR_alias_records[slot].MR_alias_words;
return MR_TRUE;
} else {
return MR_FALSE;
}
}
void
MR_trace_print_alias(FILE *fp, const char *name)
{
MR_bool found;
int slot;
MR_bsearch(MR_alias_record_next, slot, found,
strcmp(MR_alias_records[slot].MR_alias_name, name));
if (found) {
MR_trace_print_alias_num(fp, slot, MR_FALSE);
} else {
fprintf(fp, "There is no such alias.\n");
}
}
void
MR_trace_print_all_aliases(FILE *fp, MR_bool mdb_command_format)
{
int slot;
for (slot = 0; slot < MR_alias_record_next; slot++) {
MR_trace_print_alias_num(fp, slot, mdb_command_format);
}
}
static void
MR_trace_print_alias_num(FILE *fp, int slot, MR_bool mdb_command_format)
{
int i;
if (mdb_command_format) {
fprintf(fp, "alias %s", MR_alias_records[slot].MR_alias_name);
} else {
fprintf(fp, "%-6s => ", MR_alias_records[slot].MR_alias_name);
}
for (i = 0; i < MR_alias_records[slot].MR_alias_word_count; i++) {
fprintf(fp, " %s", MR_alias_records[slot].MR_alias_words[i]);
}
fprintf(fp, "\n");
}
MR_CompleterList *
MR_trace_alias_completer(const char *word, size_t word_length)
{
/*
** Remove "EMPTY" and "NUMBER" from the possible matches.
*/
return MR_trace_filter_completer(MR_trace_filter_alias_completions,
NULL, MR_trace_no_free,
MR_trace_sorted_array_completer(word, word_length,
MR_alias_record_next, MR_trace_get_alias_slot_name));
}
static char *
MR_trace_get_alias_slot_name(int slot)
{
return MR_alias_records[slot].MR_alias_name;
}
static MR_bool
MR_trace_filter_alias_completions(const char *word, MR_CompleterData *data)
{
return (MR_strdiff(word, "EMPTY") && MR_strdiff(word, "NUMBER"));
}
void
MR_trace_expand_aliases(char ***words, int *word_max, int *word_count)
{
const char *alias_key;
char **alias_words;
int alias_word_count;
int alias_copy_start;
int i;
MR_Unsigned n;
if (*word_count == 0) {
alias_key = "EMPTY";
alias_copy_start = 0;
} else if (MR_trace_is_natural_number(*words[0], &n)) {
alias_key = "NUMBER";
alias_copy_start = 0;
} else {
alias_key = *words[0];
alias_copy_start = 1;
}
if (MR_trace_lookup_alias(alias_key, &alias_words, &alias_word_count)) {
MR_ensure_big_enough(*word_count + alias_word_count, *word, char *,
MR_INIT_WORD_COUNT);
/* Move the original words (except the alias key) up. */
for (i = *word_count - 1; i >= alias_copy_start; i--) {
(*words)[i + alias_word_count - alias_copy_start] = (*words)[i];
}
/* Move the alias body to the words array. */
for (i = 0; i < alias_word_count; i++) {
(*words)[i] = alias_words[i];
}
*word_count += alias_word_count - alias_copy_start;
}
}