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); }
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); } }