X-Git-Url: http://git.efficios.com/?a=blobdiff_plain;f=gdb%2Futils.c;h=b957b0dc5c290546f52178f5183046659c30e3d9;hb=05b1d8d6fcde4805d25c9121f5b051f59580887a;hp=2f8f06fb5a340cc74a73195618c12edd34eff7c3;hpb=a738ea1d41daeec0cccb4ab6671f4f6d53bd9e18;p=deliverable%2Fbinutils-gdb.git diff --git a/gdb/utils.c b/gdb/utils.c index 2f8f06fb5a..b957b0dc5c 100644 --- a/gdb/utils.c +++ b/gdb/utils.c @@ -1,6 +1,6 @@ /* General utility routines for GDB, the GNU debugger. - Copyright (C) 1986-2017 Free Software Foundation, Inc. + Copyright (C) 1986-2018 Free Software Foundation, Inc. This file is part of GDB. @@ -70,6 +70,7 @@ #include "common/gdb_optional.h" #include "cp-support.h" #include +#include "common/pathstuff.h" #if !HAVE_DECL_MALLOC extern PTR malloc (); /* ARI: PTR */ @@ -140,36 +141,6 @@ show_pagination_enabled (struct ui_file *file, int from_tty, because while they use the "cleanup API" they are not part of the "cleanup API". */ -static void -do_free_section_addr_info (void *arg) -{ - free_section_addr_info ((struct section_addr_info *) arg); -} - -struct cleanup * -make_cleanup_free_section_addr_info (struct section_addr_info *addrs) -{ - return make_cleanup (do_free_section_addr_info, addrs); -} - -/* Helper for make_cleanup_unpush_target. */ - -static void -do_unpush_target (void *arg) -{ - struct target_ops *ops = (struct target_ops *) arg; - - unpush_target (ops); -} - -/* Return a new cleanup that unpushes OPS. */ - -struct cleanup * -make_cleanup_unpush_target (struct target_ops *ops) -{ - return make_cleanup (do_unpush_target, ops); -} - /* Helper for make_cleanup_value_free_to_mark. */ static void @@ -1199,9 +1170,7 @@ parse_escape (struct gdbarch *gdbarch, const char **string_ptr) character. */ static void -printchar (int c, void (*do_fputs) (const char *, struct ui_file *), - void (*do_fprintf) (struct ui_file *, const char *, ...) - ATTRIBUTE_FPTR_PRINTF_2, struct ui_file *stream, int quoter) +printchar (int c, do_fputc_ftype do_fputc, ui_file *stream, int quoter) { c &= 0xFF; /* Avoid sign bit follies */ @@ -1209,39 +1178,45 @@ printchar (int c, void (*do_fputs) (const char *, struct ui_file *), (c >= 0x7F && c < 0xA0) || /* DEL, High controls */ (sevenbit_strings && c >= 0x80)) { /* high order bit set */ + do_fputc ('\\', stream); + switch (c) { case '\n': - do_fputs ("\\n", stream); + do_fputc ('n', stream); break; case '\b': - do_fputs ("\\b", stream); + do_fputc ('b', stream); break; case '\t': - do_fputs ("\\t", stream); + do_fputc ('t', stream); break; case '\f': - do_fputs ("\\f", stream); + do_fputc ('f', stream); break; case '\r': - do_fputs ("\\r", stream); + do_fputc ('r', stream); break; case '\033': - do_fputs ("\\e", stream); + do_fputc ('e', stream); break; case '\007': - do_fputs ("\\a", stream); + do_fputc ('a', stream); break; default: - do_fprintf (stream, "\\%.3o", (unsigned int) c); - break; + { + do_fputc ('0' + ((c >> 6) & 0x7), stream); + do_fputc ('0' + ((c >> 3) & 0x7), stream); + do_fputc ('0' + ((c >> 0) & 0x7), stream); + break; + } } } else { if (quoter != 0 && (c == '\\' || c == quoter)) - do_fputs ("\\", stream); - do_fprintf (stream, "%c", c); + do_fputc ('\\', stream); + do_fputc (c, stream); } } @@ -1254,34 +1229,30 @@ void fputstr_filtered (const char *str, int quoter, struct ui_file *stream) { while (*str) - printchar (*str++, fputs_filtered, fprintf_filtered, stream, quoter); + printchar (*str++, fputc_filtered, stream, quoter); } void fputstr_unfiltered (const char *str, int quoter, struct ui_file *stream) { while (*str) - printchar (*str++, fputs_unfiltered, fprintf_unfiltered, stream, quoter); + printchar (*str++, fputc_unfiltered, stream, quoter); } void fputstrn_filtered (const char *str, int n, int quoter, struct ui_file *stream) { - int i; - - for (i = 0; i < n; i++) - printchar (str[i], fputs_filtered, fprintf_filtered, stream, quoter); + for (int i = 0; i < n; i++) + printchar (str[i], fputc_filtered, stream, quoter); } void fputstrn_unfiltered (const char *str, int n, int quoter, - struct ui_file *stream) + do_fputc_ftype do_fputc, struct ui_file *stream) { - int i; - - for (i = 0; i < n; i++) - printchar (str[i], fputs_unfiltered, fprintf_unfiltered, stream, quoter); + for (int i = 0; i < n; i++) + printchar (str[i], do_fputc, stream, quoter); } @@ -1490,9 +1461,7 @@ set_screen_width_and_height (int width, int height) static void prompt_for_continue (void) { - char *ignore; char cont_prompt[120]; - struct cleanup *old_chain = make_cleanup (null_cleanup, NULL); /* Used to add duration we waited for user to respond to prompt_for_continue_wait_time. */ using namespace std::chrono; @@ -1515,8 +1484,7 @@ prompt_for_continue (void) /* Call gdb_readline_wrapper, not readline, in order to keep an event loop running. */ - ignore = gdb_readline_wrapper (cont_prompt); - make_cleanup (xfree, ignore); + gdb::unique_xmalloc_ptr ignore (gdb_readline_wrapper (cont_prompt)); /* Add time spend in this routine to prompt_for_continue_wait_time. */ prompt_for_continue_wait_time += steady_clock::now () - prompt_started; @@ -1526,7 +1494,7 @@ prompt_for_continue (void) if (ignore != NULL) { - char *p = ignore; + char *p = ignore.get (); while (*p == ' ' || *p == '\t') ++p; @@ -1540,8 +1508,6 @@ prompt_for_continue (void) reinitialize_more_filter (); dont_repeat (); /* Forget prev cmd -- CR won't repeat it. */ - - do_cleanups (old_chain); } /* Initialize timer to keep track of how long we waited for the user. */ @@ -2635,13 +2601,22 @@ strcmp_iw_ordered (const char *string1, const char *string2) } } -/* A simple comparison function with opposite semantics to strcmp. */ +/* See utils.h. */ -int +bool streq (const char *lhs, const char *rhs) { return !strcmp (lhs, rhs); } + +/* See utils.h. */ + +int +streq_hash (const void *lhs, const void *rhs) +{ + return streq ((const char *) lhs, (const char *) rhs); +} + /* @@ -2838,57 +2813,6 @@ string_to_core_addr (const char *my_string) return addr; } -gdb::unique_xmalloc_ptr -gdb_realpath (const char *filename) -{ -/* On most hosts, we rely on canonicalize_file_name to compute - the FILENAME's realpath. - - But the situation is slightly more complex on Windows, due to some - versions of GCC which were reported to generate paths where - backlashes (the directory separator) were doubled. For instance: - c:\\some\\double\\slashes\\dir - ... instead of ... - c:\some\double\slashes\dir - Those double-slashes were getting in the way when comparing paths, - for instance when trying to insert a breakpoint as follow: - (gdb) b c:/some/double/slashes/dir/foo.c:4 - No source file named c:/some/double/slashes/dir/foo.c:4. - (gdb) b c:\some\double\slashes\dir\foo.c:4 - No source file named c:\some\double\slashes\dir\foo.c:4. - To prevent this from happening, we need this function to always - strip those extra backslashes. While canonicalize_file_name does - perform this simplification, it only works when the path is valid. - Since the simplification would be useful even if the path is not - valid (one can always set a breakpoint on a file, even if the file - does not exist locally), we rely instead on GetFullPathName to - perform the canonicalization. */ - -#if defined (_WIN32) - { - char buf[MAX_PATH]; - DWORD len = GetFullPathName (filename, MAX_PATH, buf, NULL); - - /* The file system is case-insensitive but case-preserving. - So it is important we do not lowercase the path. Otherwise, - we might not be able to display the original casing in a given - path. */ - if (len > 0 && len < MAX_PATH) - return gdb::unique_xmalloc_ptr (xstrdup (buf)); - } -#else - { - char *rp = canonicalize_file_name (filename); - - if (rp != NULL) - return gdb::unique_xmalloc_ptr (rp); - } -#endif - - /* This system is a lost cause, just dup the buffer. */ - return gdb::unique_xmalloc_ptr (xstrdup (filename)); -} - #if GDB_SELF_TEST static void @@ -2925,74 +2849,6 @@ gdb_realpath_tests () #endif /* GDB_SELF_TEST */ -/* Return a copy of FILENAME, with its directory prefix canonicalized - by gdb_realpath. */ - -gdb::unique_xmalloc_ptr -gdb_realpath_keepfile (const char *filename) -{ - const char *base_name = lbasename (filename); - char *dir_name; - char *result; - - /* Extract the basename of filename, and return immediately - a copy of filename if it does not contain any directory prefix. */ - if (base_name == filename) - return gdb::unique_xmalloc_ptr (xstrdup (filename)); - - dir_name = (char *) alloca ((size_t) (base_name - filename + 2)); - /* Allocate enough space to store the dir_name + plus one extra - character sometimes needed under Windows (see below), and - then the closing \000 character. */ - strncpy (dir_name, filename, base_name - filename); - dir_name[base_name - filename] = '\000'; - -#ifdef HAVE_DOS_BASED_FILE_SYSTEM - /* We need to be careful when filename is of the form 'd:foo', which - is equivalent of d:./foo, which is totally different from d:/foo. */ - if (strlen (dir_name) == 2 && isalpha (dir_name[0]) && dir_name[1] == ':') - { - dir_name[2] = '.'; - dir_name[3] = '\000'; - } -#endif - - /* Canonicalize the directory prefix, and build the resulting - filename. If the dirname realpath already contains an ending - directory separator, avoid doubling it. */ - gdb::unique_xmalloc_ptr path_storage = gdb_realpath (dir_name); - const char *real_path = path_storage.get (); - if (IS_DIR_SEPARATOR (real_path[strlen (real_path) - 1])) - result = concat (real_path, base_name, (char *) NULL); - else - result = concat (real_path, SLASH_STRING, base_name, (char *) NULL); - - return gdb::unique_xmalloc_ptr (result); -} - -/* Return PATH in absolute form, performing tilde-expansion if necessary. - PATH cannot be NULL or the empty string. - This does not resolve symlinks however, use gdb_realpath for that. */ - -gdb::unique_xmalloc_ptr -gdb_abspath (const char *path) -{ - gdb_assert (path != NULL && path[0] != '\0'); - - if (path[0] == '~') - return gdb::unique_xmalloc_ptr (tilde_expand (path)); - - if (IS_ABSOLUTE_PATH (path)) - return gdb::unique_xmalloc_ptr (xstrdup (path)); - - /* Beware the // my son, the Emacs barfs, the botch that catch... */ - return gdb::unique_xmalloc_ptr - (concat (current_directory, - IS_DIR_SEPARATOR (current_directory[strlen (current_directory) - 1]) - ? "" : SLASH_STRING, - path, (char *) NULL)); -} - ULONGEST align_up (ULONGEST v, int n) { @@ -3081,17 +2937,6 @@ compare_positive_ints (const void *ap, const void *bp) return * (int *) ap - * (int *) bp; } -/* String compare function for qsort. */ - -int -compare_strings (const void *arg1, const void *arg2) -{ - const char **s1 = (const char **) arg1; - const char **s2 = (const char **) arg2; - - return strcmp (*s1, *s2); -} - #define AMBIGUOUS_MESS1 ".\nMatching formats:" #define AMBIGUOUS_MESS2 \ ".\nUse \"set gnutarget format-name\" to specify the format." @@ -3170,30 +3015,6 @@ make_bpstat_clear_actions_cleanup (void) return make_cleanup (do_bpstat_clear_actions_cleanup, NULL); } - -/* Helper for make_cleanup_free_char_ptr_vec. */ - -static void -do_free_char_ptr_vec (void *arg) -{ - VEC (char_ptr) *char_ptr_vec = (VEC (char_ptr) *) arg; - - free_char_ptr_vec (char_ptr_vec); -} - -/* Make cleanup handler calling xfree for each element of CHAR_PTR_VEC and - final VEC_free for CHAR_PTR_VEC itself. - - You must not modify CHAR_PTR_VEC after this cleanup registration as the - CHAR_PTR_VEC base address may change on its updates. Contrary to VEC_free - this function does not (cannot) clear the pointer. */ - -struct cleanup * -make_cleanup_free_char_ptr_vec (VEC (char_ptr) *char_ptr_vec) -{ - return make_cleanup (do_free_char_ptr_vec, char_ptr_vec); -} - /* Substitute all occurences of string FROM by string TO in *STRINGP. *STRINGP must come from xrealloc-compatible allocator and it may be updated. FROM needs to be delimited by IS_DIR_SEPARATOR or DIRNAME_SEPARATOR (or be