Exemple #1
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]);
    }
}
static MR_bool
MR_trace_options_dd(MR_bool *assume_all_io_is_tabled,
    MR_Unsigned *default_depth, MR_Unsigned *num_nodes,
    MR_DeclSearchMode *search_mode, MR_bool *search_mode_was_set,
    MR_bool *search_mode_requires_trace_counts,
    char **pass_trace_counts_file, char **fail_trace_counts_file,
    MR_bool *new_session, MR_bool *reset_kb, MR_bool *testing,
    MR_bool *debug, char ***words, int *word_count)
{
    int c;

    MR_optind = 0;
    while ((c = MR_getopt_long(*word_count, *words, "ad:f:n:p:rRs:tz",
        MR_trace_dd_opts, NULL)) != EOF)
    {
        switch (c) {

            case 'a':
                *assume_all_io_is_tabled = MR_TRUE;
                break;

            case 'd':
                if (! MR_trace_is_natural_number(MR_optarg, default_depth)) {
                    MR_trace_usage_cur_cmd();
                    return MR_FALSE;
                }
                break;

            case 'f':
                *fail_trace_counts_file = MR_copy_string(MR_optarg);
                break;

            case 'n':
                if (! MR_trace_is_natural_number(MR_optarg, num_nodes)) {
                    MR_trace_usage_cur_cmd();
                    return MR_FALSE;
                }
                break;

            case 'p':
                *pass_trace_counts_file = MR_copy_string(MR_optarg);
                break;

            case 'r':
                *new_session = MR_FALSE;
                break;

            case 'R':
                *reset_kb = MR_TRUE;
                break;

            case 's':
                if (MR_trace_is_valid_search_mode_string(MR_optarg,
                    search_mode, search_mode_requires_trace_counts))
                {
                    *search_mode_was_set = MR_TRUE;
                } else {
                    MR_trace_usage_cur_cmd();
                    return MR_FALSE;
                }
                break;

            case 't':
                *testing = MR_TRUE;
                break;

            case 'z':
                *debug = MR_TRUE;
                break;

            default:
                MR_trace_usage_cur_cmd();
                return MR_FALSE;
        }
    }

    *words = *words + MR_optind - 1;
    *word_count = *word_count - MR_optind + 1;
    return MR_TRUE;
}
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);
}
Exemple #4
0
void
MR_trace_record_label_exec_counts(void *dummy)
{
    FILE        *fp;
    char        *name;
    unsigned    name_len;
    MR_bool     summarize;
    MR_bool     keep;
    char        *slash;
    const char  *program_name;

    program_name = MR_copy_string(MR_progname);
    slash = strrchr(program_name, '/');
    if (slash != NULL) {
        program_name = slash + 1;
    }

    summarize = MR_FALSE;
    keep = MR_FALSE;
    if (MR_trace_count_summary_file != NULL) {
        if (MR_FILE_EXISTS(MR_trace_count_summary_file)) {
            int     i;

            /* 30 bytes must be enough for the dot, the value of i, and '\0' */
            name_len = strlen(MR_trace_count_summary_file) + 30;
            name = MR_malloc(name_len);

            fp = NULL;
            /* search for a suffix that doesn't exist yet */
            for (i = 1; i <= MR_trace_count_summary_max; i++) {
                snprintf(name, name_len, "%s.%d",
                    MR_trace_count_summary_file, i);
                if (! MR_FILE_EXISTS(name)) {
                    /* file doesn't exist, commit to this one */
                    if (i == MR_trace_count_summary_max) {
                        summarize = MR_TRUE;
                    }

                    break;
                }
            }
        } else {
            /*
            ** The summary file doesn't yet exist, create it.
            */
            name = MR_copy_string(MR_trace_count_summary_file);
        }
    } else if (MR_trace_counts_file) {
        name = MR_copy_string(MR_trace_counts_file);
        keep = MR_TRUE;
    } else {
        char    *s;

        /*
        ** If no trace counts file name is provided, then we generate
        ** a file name.
        */

        /* 100 bytes must be enough for the process id, dots and '\0' */
        name_len = strlen(MERCURY_TRACE_COUNTS_PREFIX) + strlen(program_name)
            + 100;
        name = MR_malloc(name_len);
        snprintf(name, name_len, ".%s.%s.%d", MERCURY_TRACE_COUNTS_PREFIX,
            program_name, getpid());

        /* make sure name is an acceptable filename */
        for (s = name; *s != '\0'; s++) {
            if (*s == '/') {
                *s = '_';
            }
        }
    }

    fp = fopen(name, "w");
    if (fp != NULL) {
        unsigned    num_written;

        num_written = MR_trace_write_label_exec_counts(fp,
            program_name, MR_coverage_test_enabled);
        (void) fclose(fp);

        if (num_written == 0 && !keep) {
            /*
            ** We did not write out any trace counts, so there is nothing
            ** to gather.
            */

            (void) unlink(name);
            summarize = MR_FALSE;
        }
    } else {
        fprintf(stderr, "%s: %s\n", name, strerror(errno));
        /*
        ** You can't summarize a file list if you can't create
        ** one of its files.
        */
        summarize = MR_FALSE;
    }

    free(name);

    if (summarize) {
        char        *cmd;
        unsigned    cmd_len;
        int         summary_status;
        int         mv_status;
        int         unlink_status;
        int         i;
        const char  *old_options;

        /* 30 bytes must be enough for the dot, the value of i, and space */
        name_len = strlen(MR_trace_count_summary_file) + 30;
        name = MR_malloc(name_len);

        cmd_len = strlen(MR_trace_count_summary_cmd) + 4;
        cmd_len += strlen(MR_trace_count_summary_file)
            + strlen(TEMP_SUFFIX) + 1;
        cmd_len += (MR_trace_count_summary_max + 1) * name_len;
        cmd_len += 100;

        cmd = MR_malloc(cmd_len);

        strcpy(cmd, MR_trace_count_summary_cmd);
        strcat(cmd, " -o ");
        strcat(cmd, MR_trace_count_summary_file);
        strcat(cmd, TEMP_SUFFIX);
        strcat(cmd, " ");
        strcat(cmd, MR_trace_count_summary_file);

        for (i = 1; i <= MR_trace_count_summary_max; i++) {
            snprintf(name, name_len, "%s.%d", MR_trace_count_summary_file, i);
            strcat(cmd, " ");
            strcat(cmd, name);
        }

        strcat(cmd, " > /dev/null 2>&1");

        old_options = getenv("MERCURY_OPTIONS");
        if (old_options != NULL) {
            (void) MR_setenv("MERCURY_OPTIONS", "", MR_TRUE);
            summary_status = system(cmd);
            (void) MR_setenv("MERCURY_OPTIONS", old_options, MR_TRUE);
        } else {
            summary_status = system(cmd);
        }

        if (summary_status == 0) {
            strcpy(cmd, "mv ");
            strcat(cmd, MR_trace_count_summary_file);
            strcat(cmd, TEMP_SUFFIX);
            strcat(cmd, " ");
            strcat(cmd, MR_trace_count_summary_file);
            mv_status = system(cmd);

            if (mv_status == 0) {
                /* delete all files whose data is now in the summary file */
                for (i = 1; i <= MR_trace_count_summary_max; i++) {
                    snprintf(name, name_len, "%s.%d",
                        MR_trace_count_summary_file, i);
                    unlink_status = unlink(name);
                    if (unlink_status != 0) {
                        MR_fatal_error(
                            "couldn't create summary of trace data");
                    }
                }
            } else {
                MR_fatal_error("couldn't create summary of trace data");
            }
        } else {
            MR_fatal_error("couldn't create summary of trace data");
        }

        free(name);
        free(cmd);
    }
}