Files
mercury/trace/mercury_trace_alias.c
Mark Brown d465fa53cb Update the COPYING.LIB file and references to it.
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.

COPYING.LIB:
    Add a special linking exception to the LGPL.

*:
    Update references to COPYING.LIB.

    Clean up some minor errors that have accumulated in copyright
    messages.
2018-06-09 17:43:12 +10:00

220 lines
6.1 KiB
C

// vim: ts=4 sw=4 expandtab ft=c
// Copyright (C) 1998-2000,2002-2003, 2005-2007 The University of Melbourne.
// Copyright (C) 2016, 2018 The Mercury team.
// This file is distributed under the terms specified in COPYING.LIB.
// 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;
}
}