Exemplo n.º 1
0
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;
    }
}
Exemplo n.º 2
0
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]);
    }
}
Exemplo n.º 3
0
char *
MR_trace_readline_raw(FILE *fp)
{
    char    *contents;
    int     content_max;
    int     c;
    int     i;

    contents = NULL;
    content_max = 0;

    i = 0;
    while ((c = getc(fp)) != EOF && c != '\n') {
        MR_ensure_big_enough(i, content, char, MR_INIT_BUF_LEN);
        contents[i++] = c;
    }

    if (c == '\n' || i > 0) {
        MR_ensure_big_enough(i, content, char, MR_INIT_BUF_LEN);
        contents[i] = '\0';
        return contents;
    } else {
        MR_free(contents);
        return NULL;
    }
}
Exemplo n.º 4
0
int
MR_setenv(const char *name, const char *value, int overwrite)
{
#if defined(MR_HAVE_SETENV)
    return setenv(name, value, overwrite);
#elif defined(MR_HAVE_PUTENV) || defined(MR_HAVE__PUTENV)
    char *env;
    int length;
    int result;

    if (!overwrite && getenv(name) != NULL) {
        return 0;
    }

    length = strlen(name) + strlen(value) + 2;
    env = MR_NEW_ARRAY(char, length);

    env[0] = '\0';
    strcat(env, name);
    strcat(env, "=");
    strcat(env, value);

    result = putenv(env);

    MR_free(env);
    
    return result;
#else
  #error "MR_setenv: unable to define"
#endif
}
Exemplo n.º 5
0
MR_Next
MR_trace_cmd_trust(char **words, int word_count, MR_TraceCmdInfo *cmd,
    MR_EventInfo *event_info, MR_Code **jumpaddr)
{
    MR_ProcSpec         spec;
    MR_MatchesInfo      matches;

    if (word_count == 2) {
        spec.MR_proc_module = NULL;
        spec.MR_proc_name   = NULL;
        spec.MR_proc_arity  = -1;
        spec.MR_proc_mode   = -1;
        spec.MR_proc_prefix = (MR_ProcPrefix) -1;

        MR_register_all_modules_and_procs(MR_mdb_out, MR_TRUE);

        /* First see if the argument is a module name */
        spec.MR_proc_module = words[1];
        matches = MR_search_for_matching_procedures(&spec);
        if (matches.match_proc_next > 0) {
            MR_decl_add_trusted_module(words[1]);
            fprintf(MR_mdb_out, "Trusting module %s\n", words[1]);
        } else if (MR_parse_proc_spec(words[1], &spec)) {
            /* Check to see if the argument is a pred/func */
            matches = MR_search_for_matching_procedures(&spec);
            MR_filter_user_preds(&matches);
            if (matches.match_proc_next == 0) {
                fprintf(MR_mdb_err,
                    "mdb: there is no such module, predicate or function.\n");
            } else if (matches.match_proc_next == 1) {
                MR_decl_add_trusted_pred_or_func(matches.match_procs[0]);
                fprintf(MR_mdb_out, "Trusting ");
                MR_print_pred_id_and_nl(MR_mdb_out, matches.match_procs[0]);
            } else {
                MR_Unsigned i;
                char        buf[80];
                char        *line2;

                fprintf(MR_mdb_out, "Ambiguous predicate or function"
                    " specification. The matches are:\n");
                for (i = 0; i < matches.match_proc_next; i++) {
                    fprintf(MR_mdb_out, "%" MR_INTEGER_LENGTH_MODIFIER "u: ",
                        i);
                    MR_print_pred_id_and_nl(MR_mdb_out,
                        matches.match_procs[i]);
                }
                sprintf(buf, "\nWhich predicate or function "
                    "do you want to trust (0-%" MR_INTEGER_LENGTH_MODIFIER
                    "u or *)? ",
                    matches.match_proc_next - 1);
                line2 = MR_trace_getline(buf, MR_mdb_in, MR_mdb_out);
                if (line2 == NULL) {
                    /* This means the user input EOF. */
                    fprintf(MR_mdb_out, "none of them\n");
                } else if (MR_streq(line2, "*")) {
                    for (i = 0; i < matches.match_proc_next; i++) {
                        MR_decl_add_trusted_pred_or_func(
                            matches.match_procs[i]);

                        fprintf(MR_mdb_out, "Trusting ");
                        MR_print_pred_id_and_nl(MR_mdb_out,
                            matches.match_procs[i]);
                    }
                    MR_free(line2);
                } else if(MR_trace_is_natural_number(line2, &i)) {
                    if (0 <= i && i < matches.match_proc_next) {
                        MR_decl_add_trusted_pred_or_func(
                            matches.match_procs[i]);

                        fprintf(MR_mdb_out, "Trusting ");
                        MR_print_pred_id_and_nl(MR_mdb_out,
                            matches.match_procs[i]);
                    } else {
                        fprintf(MR_mdb_out, "no such match\n");
                    }
                    MR_free(line2);
                } else {
                    fprintf(MR_mdb_out, "none of them\n");
                    MR_free(line2);
                }
            }
        }
    } else if (word_count == 3 &&
        ((MR_streq(words[1], "std") && MR_streq(words[2], "lib"))
        || (MR_streq(words[1], "standard") && MR_streq(words[2], "library"))))
    {
        MR_decl_trust_standard_library();
        fprintf(MR_mdb_out, "Trusting the Mercury standard library\n");
    } else {
        MR_trace_usage_cur_cmd();
    }

    return KEEP_INTERACTING;
}
Exemplo n.º 6
0
char *
MR_trace_readline(const char *prompt, FILE *in, FILE *out)
{
#if (defined(isatty) || defined(MR_HAVE_ISATTY)) \
 && (defined(fileno) || defined(MR_HAVE_FILENO)) \
 && !defined(MR_NO_USE_READLINE)
    char    *line;
    MR_bool in_isatty;
    char    *last_nl;

    in_isatty = isatty(fileno(in));
    if (in_isatty || MR_force_readline) {
        rl_instream = in;
        rl_outstream = out;

        /*
        ** The cast to (void *) silences a spurious "assignment from
        ** incompatible pointer type" warning (old versions of readline
        ** are very sloppy about declaring the types of function pointers).
        */

        rl_completion_entry_function = (void *) &MR_trace_line_completer;
        rl_readline_name = "mdb";

        if (!in_isatty) {
            /*
            ** This is necessary for tests/debugger/completion, otherwise
            ** we get lots of messages about readline not being able to get
            ** the terminal settings. This is possibly a bit flaky, but it is
            ** only used by our tests.
            */
            rl_prep_term_function = (void *) MR_dummy_prep_term_function;
            rl_deprep_term_function = (void *) MR_dummy_deprep_term_function;
        }

        /*
        ** If the prompt contains newlines then readline doesn't
        ** display it properly.
        */
        last_nl = strrchr(prompt, '\n');
        if (last_nl != NULL) {
            char    *real_prompt;
            char    *pre_prompt;

            real_prompt = (char *) MR_malloc(strlen(last_nl));
            strcpy(real_prompt, last_nl + 1);
            pre_prompt = (char *) MR_malloc(last_nl - prompt + 2);
            strncpy(pre_prompt, prompt, last_nl - prompt + 1);
            pre_prompt[last_nl - prompt + 1] = '\0';
            fputs(pre_prompt, out);
            line = readline((char *) real_prompt);
            MR_free(real_prompt);
            MR_free(pre_prompt);
        } else {
            line = readline((char *) prompt);
        }

        /*
        ** readline() allocates with malloc(), and we want to return something
        ** allocated with MR_malloc(), but that's OK, because MR_malloc() and
        ** malloc() are interchangable.
        */
#if 0
        {
            char *tmp = line;

            line = MR_copy_string(line);
            free(tmp);
        }
#endif

        if (line != NULL && line[0] != '\0') {
            add_history(line);
        }

        return line;
    }
#endif /* have isatty && have fileno && !MR_NO_USE_READLINE */

    /* otherwise, don't use readline */
    fprintf(out, "%s", prompt);
    fflush(out);
    return MR_trace_readline_raw(in);
}
Exemplo n.º 7
0
char *
MR_trace_readline_from_script(FILE *fp, char **args, int num_args)
{
    char    *line = NULL;
    size_t  line_length;
    int     line_index;
    size_t  expanded_line_length;
    char    *expanded_line;
    int     expanded_line_index;
    int     arg_num;
    size_t  arg_length;
    char    *arg;

    do {
        if (line != NULL) {
            MR_free(line);
        }
        line = MR_trace_readline_raw(fp);
        if (line == NULL) {
            return NULL;
        }
        /*
        ** Ignore lines starting with '#'.
        */
    } while (*line == '#');

    line_length = strlen(line);

    expanded_line_length = line_length;
    expanded_line = (char*) MR_malloc(line_length + 1);
    expanded_line[0] = '\0';
    expanded_line_index = 0;

    for (line_index = 0; line_index < line_length; line_index++) {
        if ((line[line_index] == '$') &&
            (line_index < (line_length - 1)) &&
            (line[line_index + 1] >= '1') &&
            (line[line_index + 1] <= '9'))
        {
            arg_num = (int)(line[line_index + 1] - '1');
            if (arg_num < num_args) {
                arg = args[arg_num];
                arg_length = strlen(arg);
                /*
                ** Subtract 2 for the "$n" which will not occur
                ** in the expanded string.
                */
                expanded_line_length += arg_length - 2;
                expanded_line = MR_realloc(expanded_line,
                    expanded_line_length + 1);
                expanded_line[expanded_line_index] = '\0';
                strcat(expanded_line, arg);
                expanded_line_index += arg_length;
            }
            /* Skip the digit after the '$'. */
            line_index++;
        } else {
            expanded_line[expanded_line_index] = line[line_index];
            expanded_line_index++;
        }
    }

    MR_free(line);
    expanded_line[expanded_line_index] = '\0';

    return expanded_line;
}
Exemplo n.º 8
0
static void
MR_dump_live_variables(const MR_LabelLayout *label_layout,
    MR_MemoryZone *heap_zone, MR_bool top_frame,
    MR_Word *stack_pointer, MR_Word *current_frame)
{
    int                 short_var_count;
    int                 long_var_count;
    int                 i;
    MR_TypeInfo         type_info;
    MR_Word             value;
    MR_TypeInfoParams   type_params;
    MR_Word             saved_regs[MR_MAX_FAKE_REG];
    MR_Float            saved_f_regs[MR_MAX_VIRTUAL_F_REG];
    MR_Word             *current_regs;
    MR_Float            *current_f_regs;

    long_var_count = MR_long_desc_var_count(label_layout);
    short_var_count = MR_short_desc_var_count(label_layout);

    // For the top stack frame, we should pass a pointer to a filled-in
    // saved_regs instead of NULL. For other stack frames, passing NULL
    // is fine, since output arguments are not live yet for any call
    // except the top one.

    MR_restore_registers();
    MR_copy_regs_to_saved_regs(MR_MAX_FAKE_REG - 1, saved_regs,
        MR_MAX_VIRTUAL_F_REG - 1, saved_f_regs);
    if (top_frame) {
        current_regs = saved_regs;
        current_f_regs = saved_f_regs;
    } else {
        current_regs = NULL;
        current_f_regs = NULL;
    }
    type_params = MR_materialize_type_params_base(label_layout,
        current_regs, stack_pointer, current_frame);

    for (i = 0; i < long_var_count; i++) {
        fprintf(stderr, "%-12s\t", "");
        if (MR_PROC_LAYOUT_HAS_PROC_ID(label_layout->MR_sll_entry)) {
            MR_print_proc_id(stderr, label_layout->MR_sll_entry);
        }

        MR_dump_long_value(MR_long_desc_var_locn(label_layout, i),
            heap_zone, stack_pointer, current_frame, top_frame);
        fprintf(stderr, "\n");
        fflush(NULL);

        if (MR_debug_agc_print_vars) {
            // Call Mercury but use the debugging heap.

            MR_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min);
            MR_virtual_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min);

            if (MR_get_type_and_value_base(label_layout, i,
                    current_regs, stack_pointer, current_frame, current_f_regs,
                    type_params, &type_info, &value)) {
                printf("\t");
                MR_write_variable(type_info, value);
                printf("\n");
            }

            fflush(NULL);
        }
    }

    for (i = 0; i < short_var_count; i++) {
        fprintf(stderr, "%-12s\t", "");
        if (MR_PROC_LAYOUT_HAS_PROC_ID(label_layout->MR_sll_entry)) {
            MR_print_proc_id(stderr, label_layout->MR_sll_entry);
        }

        MR_dump_short_value(MR_short_desc_var_locn(label_layout, i),
            heap_zone, stack_pointer, current_frame, top_frame);
        fprintf(stderr, "\n");
        fflush(NULL);

        if (MR_debug_agc_print_vars) {
            // Call Mercury but use the debugging heap.

            MR_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min);
            MR_virtual_hp_word = MR_ENGINE(MR_eng_debug_heap_zone->MR_zone_min);

            if (MR_get_type_and_value_base(label_layout, i,
                    current_regs, stack_pointer, current_frame, current_f_regs,
                    type_params, &type_info, &value)) {
                printf("\t");
                MR_write_variable(type_info, value);
                printf("\n");
            }

            fflush(NULL);
        }
    }

    MR_copy_saved_regs_to_regs(MR_MAX_FAKE_REG - 1, saved_regs,
        MR_MAX_VIRTUAL_F_REG - 1, saved_f_regs);
    MR_save_registers();
    MR_free(type_params);
}
Exemplo n.º 9
0
MR_bool
MR_trace_get_action(MR_IoActionNum action_number, MR_ConstString *proc_name_ptr,
    MR_Word *is_func_ptr, MR_Word *arg_list_ptr)
{
    const MR_TableIoDecl    *table_io_decl;
    const MR_ProcLayout     *proc_layout;
    MR_ConstString          proc_name;
    MR_Word                 is_func;
    MR_Word                 arg_list;
    MR_Word                 arg;
    int                     filtered_arity;
    int                     arity;
    int                     hv;
    MR_TrieNode             answer_block_trie;
    MR_Word                 *answer_block;
    MR_TypeInfo             *type_params;
    MR_TypeInfo             type_info;

    if (! (MR_io_tabling_start <= action_number
        && action_number < MR_io_tabling_counter_hwm))
    {
        return MR_FALSE;
    }

    MR_TABLE_START_INT(NULL, MR_tabledebug, MR_FALSE,
        answer_block_trie, (MR_TrieNode) &MR_io_tabling_pointer,
        MR_io_tabling_start, action_number);
    answer_block = answer_block_trie->MR_answerblock;

    if (answer_block == NULL) {
        return MR_FALSE;
    }

    table_io_decl = (const MR_TableIoDecl *) answer_block[0];
    proc_layout = table_io_decl->MR_table_io_decl_proc;
    filtered_arity = table_io_decl->MR_table_io_decl_filtered_arity;

    MR_generate_proc_name_from_layout(proc_layout, &proc_name, &arity,
        &is_func);

    type_params = MR_materialize_answer_block_type_params(
        table_io_decl->MR_table_io_decl_type_params, answer_block,
        filtered_arity);

    MR_restore_transient_hp();
    arg_list = MR_list_empty();
    MR_save_transient_hp();
    for (hv = filtered_arity; hv >= 1; hv--) {
        type_info = MR_create_type_info(type_params,
            table_io_decl->MR_table_io_decl_ptis[hv - 1]);
        MR_restore_transient_hp();
        MR_new_univ_on_hp(arg, type_info, answer_block[hv]);
        arg_list = MR_univ_list_cons(arg, arg_list);
        MR_save_transient_hp();
    }

    MR_free(type_params);

    *proc_name_ptr = proc_name;
    *is_func_ptr = is_func;
    *arg_list_ptr = arg_list;
    return MR_TRUE;
}
Exemplo n.º 10
0
const char *
MR_trace_source_open_server(MR_TraceSourceServer *server,
    const char *window_cmd, int timeout, MR_bool verbose)
{
    const char  *real_window_cmd;
    const char  *real_server_cmd;
    char        *name;
    const char  *msg;
    char        system_call[MR_SYSCALL_BUFFER_SIZE];
    int         status;
    size_t      base_len;
    size_t      i;

    if (window_cmd != NULL) {
        real_window_cmd = window_cmd;
    } else {
        real_window_cmd = MR_DEFAULT_SOURCE_WINDOW_COMMAND;
    }

    if (server->server_cmd != NULL) {
        real_server_cmd = server->server_cmd;
    } else {
        real_server_cmd = MR_DEFAULT_SOURCE_SERVER_COMMAND;
    }

    // 1) check that display is set;
    // 2) check that server is valid;
    // 3) start a server with a unique name;
    // 4) wait until the server is found;
    // 5) (if required) split the window.

    msg = MR_trace_source_check_display();
    if (msg != NULL) {
        return msg;
    }

    msg = MR_trace_source_check_server_cmd(real_server_cmd, verbose);
    if (msg != NULL) {
        return msg;
    }

    // If possible, we generate a unique name of the form
    // '<basename>.<hostname>.<pid>', but if the required functions
    // aren't available, we fall back to appending numbers to the
    // basename in sequence until one is found that is not being used.
    // This is quite a slow way of doing things, and there is also a
    // race condition, but it is difficult to see a better way.
    // We should let the server pick a unique name for itself, but
    // how would you communicate this name back to this process?

    base_len = strlen(MR_SOURCE_SERVER_BASENAME);

#if defined(MR_HAVE_GETPID) && defined(MR_HAVE_GETHOSTNAME)
    // Need to leave enough room for the pid, two '.'s and the
    // terminating zero.

    name = MR_malloc(base_len + MR_SERVER_HOSTNAME_CHARS + 32);
    strcpy(name, MR_SOURCE_SERVER_BASENAME);

    // Append the '.' and hostname.

    name[base_len] = '.';
    gethostname(name + base_len + 1, MR_SERVER_HOSTNAME_CHARS);
    // Do this just in case gethostname didn't terminate the string:
    name[base_len + 1 + MR_SERVER_HOSTNAME_CHARS] = '\0';

    // Find the end of the string and append the '.' and pid.

    i = base_len + 1 + strlen(name + base_len + 1);
    sprintf(name + i, ".%ld", (long) getpid());
#else
    i = 0;
    // Need to leave enough room for a '.', the integer and the
    // terminating zero.

    name = MR_malloc(base_len + 10);
    do {
        i++;
        sprintf(name, "%s.%lu", MR_SOURCE_SERVER_BASENAME, (unsigned long)i);
        // This should fail if there is no server with this name.
        msg = MR_trace_source_check_server(real_server_cmd, name, verbose);
    } while (msg == NULL);
#endif

    server->server_name = name;

    // Start the server in read-only mode, to discourage the user
    // from trying to edit the source.

    sprintf(system_call, "%s %s -R --servername \"%s\" %s &", real_window_cmd,
        real_server_cmd, name, (verbose ? "" : "> /dev/null 2>&1"));
    MR_verbose_system_call(system_call, verbose);

    // We need to wait until the source server has registered itself
    // with the X server. If we don't, we may execute remote commands
    // before the server has started up, and this will result in vim
    // (rather inconveniently) starting its own server on mdb's terminal.

    msg = MR_trace_source_attach(server, timeout, verbose);

    if (msg != NULL) {
        // Something went wrong, so we should free the server name
        // we allocated just above.

        MR_free(server->server_name);
        server->server_name = NULL;
        return msg;
    }

    if (server->split) {
        // Split the window.
        status = MR_trace_source_send(real_server_cmd, server->server_name,
            MR_SOURCE_SERVER_RESET_STRING MR_SOURCE_SERVER_SPLIT_STRING,
            verbose);
        if (status != 0) {
            server->split = MR_FALSE;
            return "warning: unable to split source window";
        }
    }

    return NULL;
}
Exemplo n.º 11
0
MR_bool
MR_trace_get_action(MR_IoActionNum action_number, MR_ConstString *proc_name_ptr,
    MR_Word *is_func_ptr, MR_bool *have_arg_infos_ptr, MR_Word *arg_list_ptr)
{
    const MR_TableIoEntry   *table_io_entry;
    const MR_ProcLayout     *proc_layout;
    MR_ConstString          proc_name;
    MR_Word                 is_func;
    int                     arity;
    int                     hv;
    MR_TrieNode             answer_block_trie;
    MR_Word                 *answer_block;

    if (! (MR_io_tabling_start <= action_number
        && action_number < MR_io_tabling_counter_hwm))
    {
        return MR_FALSE;
    }

    MR_TABLE_START_INT(NULL, MR_tabledebug, MR_FALSE,
        answer_block_trie, (MR_TrieNode) &MR_io_tabling_pointer,
        MR_io_tabling_start, action_number);
    answer_block = answer_block_trie->MR_answerblock;

    if (answer_block == NULL) {
        return MR_FALSE;
    }

    table_io_entry = (const MR_TableIoEntry *) answer_block[0];
    proc_layout = table_io_entry->MR_table_io_entry_proc;
    MR_generate_proc_name_from_layout(proc_layout, &proc_name, &arity,
        &is_func);
    *proc_name_ptr = proc_name;
    *is_func_ptr = is_func;

    if (table_io_entry->MR_table_io_entry_have_arg_infos) {
        int         filtered_arity;
        MR_Word     arg_list;
        MR_Word     arg;
        MR_TypeInfo *type_params;
        MR_TypeInfo type_info;

        *have_arg_infos_ptr = MR_TRUE;
        filtered_arity = table_io_entry->MR_table_io_entry_num_ptis;
        type_params = MR_materialize_answer_block_type_params(
            table_io_entry->MR_table_io_entry_type_params, answer_block,
            filtered_arity);

        MR_restore_transient_hp();
        arg_list = MR_list_empty();
        MR_save_transient_hp();
        for (hv = filtered_arity; hv >= 1; hv--) {
            type_info = MR_create_type_info(type_params,
                table_io_entry->MR_table_io_entry_ptis[hv - 1]);
            MR_restore_transient_hp();
            MR_new_univ_on_hp(arg, type_info, answer_block[hv]);
            arg_list = MR_univ_list_cons(arg, arg_list);
            MR_save_transient_hp();
        }

        MR_free(type_params);
        *arg_list_ptr = arg_list;
    } else {
        *have_arg_infos_ptr = MR_FALSE;
        // *arg_list_ptr is not meaningful when *have_arg_infos_ptr is false,
        // but setting it to the empty list makes it easier to catch any
        // caller that ignores that fact.
        *arg_list_ptr = MR_list_empty();
    }

    return MR_TRUE;
}