X-Git-Url: http://review.tizen.org/git/?a=blobdiff_plain;f=gdb%2Fcompleter.c;h=07facfb012c1e0a196c784cb65108d028640338b;hb=bb01dbfc041dccab2f2a2818068158f61b4c0fe2;hp=769dcf0eb635d23255ded4cd4349fc210fd1c885;hpb=459a2e4ccf9aadfba9819facba1c9be5297c1625;p=external%2Fbinutils.git diff --git a/gdb/completer.c b/gdb/completer.c index 769dcf0..07facfb 100644 --- a/gdb/completer.c +++ b/gdb/completer.c @@ -1,5 +1,5 @@ /* Line completion stuff for GDB, the GNU debugger. - Copyright (C) 2000-2018 Free Software Foundation, Inc. + Copyright (C) 2000-2019 Free Software Foundation, Inc. This file is part of GDB. @@ -22,7 +22,7 @@ #include "expression.h" #include "filenames.h" /* For DOSish file names. */ #include "language.h" -#include "gdb_signals.h" +#include "gdbsupport/gdb_signals.h" #include "target.h" #include "reggroups.h" #include "user-regs.h" @@ -352,29 +352,58 @@ gdb_rl_find_completion_word (struct gdb_rl_completion_word_info *info, return line_buffer + point; } -/* See completer.h. */ +/* Find the completion word point for TEXT, emulating the algorithm + readline uses to find the word point, using WORD_BREAK_CHARACTERS + as word break characters. */ -const char * -advance_to_expression_complete_word_point (completion_tracker &tracker, - const char *text) +static const char * +advance_to_completion_word (completion_tracker &tracker, + const char *word_break_characters, + const char *text) { gdb_rl_completion_word_info info; - info.word_break_characters - = current_language->la_word_break_characters (); + info.word_break_characters = word_break_characters; info.quote_characters = gdb_completer_quote_characters; info.basic_quote_characters = rl_basic_quote_characters; + int delimiter; const char *start - = gdb_rl_find_completion_word (&info, NULL, NULL, text); + = gdb_rl_find_completion_word (&info, NULL, &delimiter, text); tracker.advance_custom_word_point_by (start - text); + if (delimiter) + { + tracker.set_quote_char (delimiter); + tracker.set_suppress_append_ws (true); + } + return start; } /* See completer.h. */ +const char * +advance_to_expression_complete_word_point (completion_tracker &tracker, + const char *text) +{ + const char *brk_chars = current_language->la_word_break_characters (); + return advance_to_completion_word (tracker, brk_chars, text); +} + +/* See completer.h. */ + +const char * +advance_to_filename_complete_word_point (completion_tracker &tracker, + const char *text) +{ + const char *brk_chars = gdb_completer_file_name_break_characters; + return advance_to_completion_word (tracker, brk_chars, text); +} + +/* See completer.h. */ + bool completion_tracker::completes_to_completion_word (const char *word) { @@ -394,6 +423,39 @@ completion_tracker::completes_to_completion_word (const char *word) return false; } +/* See completer.h. */ + +void +complete_nested_command_line (completion_tracker &tracker, const char *text) +{ + /* Must be called from a custom-word-point completer. */ + gdb_assert (tracker.use_custom_word_point ()); + + /* Disable the custom word point temporarily, because we want to + probe whether the command we're completing itself uses a custom + word point. */ + tracker.set_use_custom_word_point (false); + size_t save_custom_word_point = tracker.custom_word_point (); + + int quote_char = '\0'; + const char *word = completion_find_completion_word (tracker, text, + "e_char); + + if (tracker.use_custom_word_point ()) + { + /* The command we're completing uses a custom word point, so the + tracker already contains the matches. We're done. */ + return; + } + + /* Restore the custom word point settings. */ + tracker.set_custom_word_point (save_custom_word_point); + tracker.set_use_custom_word_point (true); + + /* Run the handle_completions completer phase. */ + complete_line (tracker, word, text, strlen (text)); +} + /* Complete on linespecs, which might be of two possible forms: file:line @@ -798,9 +860,7 @@ complete_explicit_location (completion_tracker &tracker, before: "b -function 'not_loaded_function_yet()'" after: "b -function 'not_loaded_function_yet()' " */ - gdb::unique_xmalloc_ptr text_copy - (xstrdup (text)); - tracker.add_completion (std::move (text_copy)); + tracker.add_completion (make_unique_xstrdup (text)); } else if (quoted_arg_end[1] == ' ') { @@ -999,7 +1059,7 @@ add_struct_fields (struct type *type, completion_list &output, { if (!computed_type_name) { - type_name = type_name_no_tag (type); + type_name = TYPE_NAME (type); computed_type_name = 1; } /* Omit constructors from the completion list. */ @@ -1021,15 +1081,14 @@ complete_expression (completion_tracker &tracker, /* Perform a tentative parse of the expression, to see whether a field completion is required. */ - TRY + try { type = parse_expression_for_completion (text, &fieldname, &code); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { return; } - END_CATCH if (fieldname != nullptr && type) { @@ -1399,6 +1458,9 @@ complete_line_internal_1 (completion_tracker &tracker, break; } + /* Move the custom word point back too. */ + tracker.advance_custom_word_point_by (q - p); + if (reason != handle_brkchars) complete_on_cmdlist (result_list, tracker, q, word, ignore_help_classes); @@ -1445,16 +1507,15 @@ complete_line_internal (completion_tracker &tracker, const char *line_buffer, int point, complete_line_internal_reason reason) { - TRY + try { complete_line_internal_1 (tracker, text, line_buffer, point, reason); } - CATCH (except, RETURN_MASK_ERROR) + catch (const gdb_exception_error &except) { if (except.error != MAX_COMPLETIONS_REACHED_ERROR) - throw_exception (except); + throw; } - END_CATCH } /* See completer.h. */ @@ -1615,6 +1676,48 @@ make_completion_match_str (gdb::unique_xmalloc_ptr &&match_name, return gdb::unique_xmalloc_ptr (newobj); } +/* See complete.h. */ + +completion_result +complete (const char *line, char const **word, int *quote_char) +{ + completion_tracker tracker_handle_brkchars; + completion_tracker tracker_handle_completions; + completion_tracker *tracker; + + /* The WORD should be set to the end of word to complete. We initialize + to the completion point which is assumed to be at the end of LINE. + This leaves WORD to be initialized to a sensible value in cases + completion_find_completion_word() fails i.e., throws an exception. + See bug 24587. */ + *word = line + strlen (line); + + try + { + *word = completion_find_completion_word (tracker_handle_brkchars, + line, quote_char); + + /* Completers that provide a custom word point in the + handle_brkchars phase also compute their completions then. + Completers that leave the completion word handling to readline + must be called twice. */ + if (tracker_handle_brkchars.use_custom_word_point ()) + tracker = &tracker_handle_brkchars; + else + { + complete_line (tracker_handle_completions, *word, line, strlen (line)); + tracker = &tracker_handle_completions; + } + } + catch (const gdb_exception &ex) + { + return {}; + } + + return tracker->build_completion_result (*word, *word - line, strlen (line)); +} + + /* Generate completions all at once. Does nothing if max_completions is 0. If max_completions is non-negative, this will collect at most max_completions strings. @@ -1683,10 +1786,7 @@ signal_completer (struct cmd_list_element *ignore, continue; if (strncasecmp (signame, word, len) == 0) - { - gdb::unique_xmalloc_ptr copy (xstrdup (signame)); - tracker.add_completion (std::move (copy)); - } + tracker.add_completion (make_unique_xstrdup (signame)); } } @@ -1725,10 +1825,7 @@ reg_or_group_completer_1 (completion_tracker &tracker, i++) { if (*name != '\0' && strncmp (word, name, len) == 0) - { - gdb::unique_xmalloc_ptr copy (xstrdup (name)); - tracker.add_completion (std::move (copy)); - } + tracker.add_completion (make_unique_xstrdup (name)); } } @@ -1742,10 +1839,7 @@ reg_or_group_completer_1 (completion_tracker &tracker, { name = reggroup_name (group); if (strncmp (word, name, len) == 0) - { - gdb::unique_xmalloc_ptr copy (xstrdup (name)); - tracker.add_completion (std::move (copy)); - } + tracker.add_completion (make_unique_xstrdup (name)); } } } @@ -1833,6 +1927,9 @@ gdb_completion_word_break_characters_throw () { gdb_assert (tracker.custom_word_point () > 0); rl_point = tracker.custom_word_point () - 1; + + gdb_assert (rl_point >= 0 && rl_point < strlen (rl_line_buffer)); + gdb_custom_word_point_brkchars[0] = rl_line_buffer[rl_point]; rl_completer_word_break_characters = gdb_custom_word_point_brkchars; rl_completer_quote_characters = NULL; @@ -1859,17 +1956,16 @@ gdb_completion_word_break_characters () /* New completion starting. */ current_completion.aborted = false; - TRY + try { return gdb_completion_word_break_characters_throw (); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { /* Set this to that gdb_rl_attempted_completion_function knows to abort early. */ current_completion.aborted = true; } - END_CATCH return NULL; } @@ -1937,7 +2033,7 @@ completion_tracker::recompute_lowest_common_denominator /* See completer.h. */ void -completion_tracker::advance_custom_word_point_by (size_t len) +completion_tracker::advance_custom_word_point_by (int len) { m_custom_word_point += len; } @@ -2032,7 +2128,7 @@ completion_tracker::build_completion_result (const char *text, /* We don't rely on readline appending the quote char as delimiter as then readline wouldn't append the ' ' after the completion. */ - char buf[2] = { quote_char () }; + char buf[2] = { (char) quote_char () }; match_list[0] = reconcat (match_list[0], match_list[0], buf, (char *) NULL); @@ -2207,14 +2303,13 @@ gdb_rl_attempted_completion_function (const char *text, int start, int end) if (current_completion.aborted) return NULL; - TRY + try { return gdb_rl_attempted_completion_function_throw (text, start, end); } - CATCH (ex, RETURN_MASK_ALL) + catch (const gdb_exception &ex) { } - END_CATCH return NULL; }