示例#1
0
const char *
MR_trace_source_sync(MR_TraceSourceServer *server, const char *filename,
    int lineno, const char *parent_filename, int parent_lineno,
    MR_bool verbose)
{
    const char  *real_server_cmd;
    const char  *msg;
    int         status;
    MR_bool     have_parent;
    MR_bool     have_current;

    have_parent = MR_strdiff(parent_filename, "") && parent_lineno != 0;
    have_current = MR_strdiff(filename, "") && lineno != 0;

    if (!have_parent && !have_current) {
        // No point in continuing.
        return NULL;
    }

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

    msg = MR_trace_source_check_server(real_server_cmd, server->server_name,
        verbose);
    if (msg != NULL) {
        return msg;
    }

    if (server->split) {
        // When in split mode, we open two windows on the vim server,
        // a primary window and the secondary window. The primary window
        // displays what would normally be shown in non-split mode.
        //
        // If there is no parent context (e.g. at internal events)
        // we leave the secondary window alone.
        //
        // If we have a parent context it will be displayed in the
        // primary window, so in this case we show the current context
        // in the secondary window.
        //
        // The primary window is the one second from the top (which will
        // usually be the bottom window). The secondary window is at the top.

        if (have_parent && have_current) {
            // Move to the secondary (top) window.
            status = MR_trace_source_send(real_server_cmd, server->server_name,
                MR_SOURCE_SERVER_RESET_STRING MR_SOURCE_SERVER_TOP_STRING,
                verbose);
            if (status != 0) {
                return "warning: source synchronisation failed";
            }

            msg = MR_trace_source_jump(real_server_cmd, server->server_name,
                filename, lineno, verbose);
            if (msg != NULL) {
                return msg;
            }

            // Move down one window to the primary.
            status = MR_trace_source_send(real_server_cmd, server->server_name,
                MR_SOURCE_SERVER_RESET_STRING MR_SOURCE_SERVER_DOWN_STRING,
                verbose);
            if (status != 0) {
                return "warning: source synchronisation failed";
            }
        } else {
            // Move to the primary (second from top) window.
            status = MR_trace_source_send(real_server_cmd, server->server_name,
                MR_SOURCE_SERVER_RESET_STRING MR_SOURCE_SERVER_TOP_STRING
                MR_SOURCE_SERVER_DOWN_STRING, verbose);
            if (status != 0) {
                return "warning: source synchronisation failed";
            }
        }
    }

    // We show the parent context if we can, since if both are present
    // the parent context is usually more interesting. Otherwise we
    // show the current context.

    if (have_parent) {
        msg = MR_trace_source_jump(real_server_cmd, server->server_name,
            parent_filename, parent_lineno, verbose);
        if (msg != NULL) {
            return msg;
        }
    } else {
        msg = MR_trace_source_jump(real_server_cmd, server->server_name,
            filename, lineno, verbose);
        if (msg != NULL) {
            return msg;
        }
    }

    return NULL;
}
示例#2
0
static unsigned
MR_trace_write_label_exec_counts_for_file(FILE *fp,
    const MR_ModuleLayout *module, const MR_ModuleFileLayout *file,
    const char *module_name, MR_bool coverage_test)
{
    const MR_LabelLayout        *label;
    const MR_ProcLayout         *prev_proc;
    const MR_ProcLayout         *proc;
    const MR_UserProcId         *id;
    MR_TracePort                port;
    int                         num_labels;
    int                         label_num;
    int                         label_index;
    unsigned                    num_written;
    MR_Unsigned                 exec_count;
    MR_PathPort                 path_port;

    fputs("file ", fp);
    MR_trace_write_quoted_atom(fp, file->MR_mfl_filename);
    fputc('\n', fp);

    prev_proc = NULL;
    num_labels = file->MR_mfl_label_count;
    num_written = 0;
    for (label_num = 0; label_num < num_labels; label_num++) {
        label = file->MR_mfl_label_layout[label_num];
        proc = label->MR_sll_entry;
        label_index = label->MR_sll_label_num_in_module;
        exec_count = module->MR_ml_label_exec_count[label_index];
        if (! MR_PROC_LAYOUT_IS_UCI(proc) && label_index > 0 &&
            (exec_count > 0 || coverage_test))
        {
            num_written++;

            id = &proc->MR_sle_user;
            if (proc != prev_proc) {
                if (MR_strdiff(module_name, id->MR_user_def_module)) {
                    MR_fatal_error(
                        "MR_trace_write_label_exec_counts_for_file: "
                        "module name mismatch");
                }

                if (id->MR_user_pred_or_func == MR_PREDICATE) {
                    fputs("pproc", fp);
                } else {
                    fputs("fproc", fp);
                }

                if (MR_strdiff(module_name, id->MR_user_decl_module)) {
                    /* turn pproc/fproc into pprocdecl/fprocdecl */
                    fputs("decl ", fp);
                    MR_trace_write_quoted_atom(fp, id->MR_user_decl_module);
                }

                fputc(' ', fp);
                MR_trace_write_quoted_atom(fp, id->MR_user_name);
                fprintf(fp, " %d %d\n", id->MR_user_arity, id->MR_user_mode);
            }

            port = label->MR_sll_port;
            path_port = MR_named_count_port[port];

            switch (path_port) {

                case PORT_ONLY:
                    fputs(MR_actual_port_names[port], fp);
                    break;

                case PATH_ONLY:
                    putc('<', fp);
                    fputs(MR_label_goal_path(label), fp);
                    putc('>', fp);
                    break;

                case PORT_AND_PATH:
                    fputs(MR_actual_port_names[port], fp);
                    putc(' ', fp);
                    putc('<', fp);
                    fputs(MR_label_goal_path(label), fp);
                    putc('>', fp);
                    break;

                default:
                    MR_fatal_error(
                        "MR_trace_write_label_exec_counts_for_file: "
                        "bad path_port");
                    break;
            }

            putc(' ', fp);
            fprintf(fp, "%d", file->MR_mfl_label_lineno[label_num]);

            if (exec_count > 0) {
                putc(' ', fp);
                fprintf(fp, "%" MR_INTEGER_LENGTH_MODIFIER "u", exec_count);
            }

            putc('\n', fp);

            prev_proc = proc;
        }
    }

    return num_written;
}
示例#3
0
static MR_bool
MR_trace_filter_alias_completions(const char *word, MR_CompleterData *data)
{
    return (MR_strdiff(word, "EMPTY") && MR_strdiff(word, "NUMBER"));
}