Convert AutoComplete related code to StringRef.
authorZachary Turner <zturner@google.com>
Thu, 17 Nov 2016 01:37:42 +0000 (01:37 +0000)
committerZachary Turner <zturner@google.com>
Thu, 17 Nov 2016 01:37:42 +0000 (01:37 +0000)
Differential Revision: https://reviews.llvm.org/D26721

llvm-svn: 287188

32 files changed:
lldb/include/lldb/Core/ArchSpec.h
lldb/include/lldb/Core/FormatEntity.h
lldb/include/lldb/Core/PluginManager.h
lldb/include/lldb/Core/StringList.h
lldb/include/lldb/Core/UUID.h
lldb/include/lldb/Interpreter/CommandCompletions.h
lldb/include/lldb/Interpreter/OptionValue.h
lldb/include/lldb/Interpreter/OptionValueArch.h
lldb/include/lldb/Interpreter/OptionValueBoolean.h
lldb/include/lldb/Interpreter/OptionValueEnumeration.h
lldb/include/lldb/Interpreter/OptionValueFileSpec.h
lldb/include/lldb/Interpreter/OptionValueFormatEntity.h
lldb/include/lldb/Interpreter/OptionValueUUID.h
lldb/include/lldb/Symbol/Variable.h
lldb/include/lldb/Utility/NameMatches.h
lldb/source/Commands/CommandCompletions.cpp
lldb/source/Core/ArchSpec.cpp
lldb/source/Core/FormatEntity.cpp
lldb/source/Core/PluginManager.cpp
lldb/source/Core/StringList.cpp
lldb/source/Core/UUID.cpp
lldb/source/Interpreter/CommandObject.cpp
lldb/source/Interpreter/OptionValue.cpp
lldb/source/Interpreter/OptionValueArch.cpp
lldb/source/Interpreter/OptionValueBoolean.cpp
lldb/source/Interpreter/OptionValueEnumeration.cpp
lldb/source/Interpreter/OptionValueFileSpec.cpp
lldb/source/Interpreter/OptionValueFormatEntity.cpp
lldb/source/Interpreter/OptionValueUUID.cpp
lldb/source/Plugins/Instruction/ARM64/EmulateInstructionARM64.cpp
lldb/source/Symbol/Variable.cpp
lldb/source/Utility/NameMatches.cpp

index 84613c5..7f663f7 100644 (file)
@@ -283,7 +283,7 @@ public:
   //------------------------------------------------------------------
   const ArchSpec &operator=(const ArchSpec &rhs);
 
-  static size_t AutoComplete(const char *name, StringList &matches);
+  static size_t AutoComplete(llvm::StringRef name, StringList &matches);
 
   //------------------------------------------------------------------
   /// Returns a static string representing the current architecture.
index 564bd5c..b6fe9ea 100644 (file)
@@ -192,7 +192,7 @@ public:
                                    llvm::StringRef &variable_name,
                                    llvm::StringRef &variable_format);
 
-  static size_t AutoComplete(const char *s, int match_start_point,
+  static size_t AutoComplete(llvm::StringRef s, int match_start_point,
                              int max_return_elements, bool &word_complete,
                              StringList &matches);
 
index 636004b..e0de65a 100644 (file)
@@ -244,7 +244,7 @@ public:
 
   static const char *GetPlatformPluginDescriptionAtIndex(uint32_t idx);
 
-  static size_t AutoCompletePlatformName(const char *partial_name,
+  static size_t AutoCompletePlatformName(llvm::StringRef partial_name,
                                          StringList &matches);
   //------------------------------------------------------------------
   // Process
index b7df701..2cd974d 100644 (file)
@@ -109,7 +109,7 @@ public:
   // values in this collection, will have "exact_matches_idx"
   // filled in to match the index, or "exact_matches_idx" will
   // have SIZE_MAX
-  size_t AutoComplete(const char *s, StringList &matches,
+  size_t AutoComplete(llvm::StringRef s, StringList &matches,
                       size_t &exact_matches_idx) const;
 
   // Dump the StringList to the given lldb_private::Log, `log`, one item per
index 12cd84c..de1e697 100644 (file)
@@ -68,19 +68,12 @@ public:
   ///     A buffer of bytes that will contain a full or patially
   ///     decoded UUID.
   ///
-  /// @param[out] end
-  ///     If \a end is not nullptr, it will be filled in with the a
-  ///     pointer to the character after the last successfully decoded
-  ///     byte.
-  ///
   /// @return
-  ///     Returns the number of bytes that were successfully decoded
-  ///     which should be 16 if a full UUID value was properly decoded.
+  ///     The original string, with all decoded bytes removed.
   //------------------------------------------------------------------
-  static size_t DecodeUUIDBytesFromCString(const char *cstr,
-                                           ValueType &uuid_bytes,
-                                           const char **end,
-                                           uint32_t num_uuid_bytes = 16);
+  static llvm::StringRef
+  DecodeUUIDBytesFromString(llvm::StringRef str, ValueType &uuid_bytes,
+                            uint32_t num_uuid_bytes = 16);
 
 protected:
   //------------------------------------------------------------------
index c546a1a..2e11735 100644 (file)
@@ -32,7 +32,7 @@ public:
   //----------------------------------------------------------------------
   typedef int (*CompletionCallback)(
       CommandInterpreter &interpreter,
-      const char *completion_str, // This is the argument we are completing
+      llvm::StringRef completion_str, // This is the argument we are completing
       int match_start_point,   // This is the point in the list of matches that
                                // you should start returning elements
       int max_return_elements, // This is the number of matches requested.
@@ -64,7 +64,7 @@ public:
 
   static bool InvokeCommonCompletionCallbacks(
       CommandInterpreter &interpreter, uint32_t completion_mask,
-      const char *completion_str, int match_start_point,
+      llvm::StringRef completion_str, int match_start_point,
       int max_return_elements, SearchFilter *searcher, bool &word_complete,
       StringList &matches);
 
@@ -72,53 +72,54 @@ public:
   // These are the generic completer functions:
   //----------------------------------------------------------------------
   static int DiskFiles(CommandInterpreter &interpreter,
-                       const char *partial_file_name, int match_start_point,
+                       llvm::StringRef partial_file_name, int match_start_point,
                        int max_return_elements, SearchFilter *searcher,
                        bool &word_complete, StringList &matches);
 
   static int DiskDirectories(CommandInterpreter &interpreter,
-                             const char *partial_file_name,
+                             llvm::StringRef partial_file_name,
                              int match_start_point, int max_return_elements,
                              SearchFilter *searcher, bool &word_complete,
                              StringList &matches);
 
   static int SourceFiles(CommandInterpreter &interpreter,
-                         const char *partial_file_name, int match_start_point,
-                         int max_return_elements, SearchFilter *searcher,
-                         bool &word_complete, StringList &matches);
+                         llvm::StringRef partial_file_name,
+                         int match_start_point, int max_return_elements,
+                         SearchFilter *searcher, bool &word_complete,
+                         StringList &matches);
 
   static int Modules(CommandInterpreter &interpreter,
-                     const char *partial_file_name, int match_start_point,
+                     llvm::StringRef partial_file_name, int match_start_point,
                      int max_return_elements, SearchFilter *searcher,
                      bool &word_complete, lldb_private::StringList &matches);
 
   static int Symbols(CommandInterpreter &interpreter,
-                     const char *partial_file_name, int match_start_point,
+                     llvm::StringRef partial_file_name, int match_start_point,
                      int max_return_elements, SearchFilter *searcher,
                      bool &word_complete, lldb_private::StringList &matches);
 
   static int SettingsNames(CommandInterpreter &interpreter,
-                           const char *partial_file_name, int match_start_point,
-                           int max_return_elements, SearchFilter *searcher,
-                           bool &word_complete,
+                           llvm::StringRef partial_file_name,
+                           int match_start_point, int max_return_elements,
+                           SearchFilter *searcher, bool &word_complete,
                            lldb_private::StringList &matches);
 
   static int PlatformPluginNames(CommandInterpreter &interpreter,
-                                 const char *partial_file_name,
+                                 llvm::StringRef partial_file_name,
                                  int match_start_point, int max_return_elements,
                                  SearchFilter *searcher, bool &word_complete,
                                  lldb_private::StringList &matches);
 
   static int ArchitectureNames(CommandInterpreter &interpreter,
-                               const char *partial_file_name,
+                               llvm::StringRef partial_file_name,
                                int match_start_point, int max_return_elements,
                                SearchFilter *searcher, bool &word_complete,
                                lldb_private::StringList &matches);
 
   static int VariablePath(CommandInterpreter &interpreter,
-                          const char *partial_file_name, int match_start_point,
-                          int max_return_elements, SearchFilter *searcher,
-                          bool &word_complete,
+                          llvm::StringRef partial_file_name,
+                          int match_start_point, int max_return_elements,
+                          SearchFilter *searcher, bool &word_complete,
                           lldb_private::StringList &matches);
 
   //----------------------------------------------------------------------
@@ -128,7 +129,7 @@ public:
   //----------------------------------------------------------------------
   class Completer : public Searcher {
   public:
-    Completer(CommandInterpreter &interpreter, const char *completion_str,
+    Completer(CommandInterpreter &interpreter, llvm::StringRef completion_str,
               int match_start_point, int max_return_elements,
               StringList &matches);
 
@@ -158,9 +159,9 @@ public:
   class SourceFileCompleter : public Completer {
   public:
     SourceFileCompleter(CommandInterpreter &interpreter,
-                        bool include_support_files, const char *completion_str,
-                        int match_start_point, int max_return_elements,
-                        StringList &matches);
+                        bool include_support_files,
+                        llvm::StringRef completion_str, int match_start_point,
+                        int max_return_elements, StringList &matches);
 
     Searcher::Depth GetDepth() override;
 
@@ -185,9 +186,9 @@ public:
   //----------------------------------------------------------------------
   class ModuleCompleter : public Completer {
   public:
-    ModuleCompleter(CommandInterpreter &interpreter, const char *completion_str,
-                    int match_start_point, int max_return_elements,
-                    StringList &matches);
+    ModuleCompleter(CommandInterpreter &interpreter,
+                    llvm::StringRef completion_str, int match_start_point,
+                    int max_return_elements, StringList &matches);
 
     Searcher::Depth GetDepth() override;
 
@@ -210,9 +211,9 @@ public:
   //----------------------------------------------------------------------
   class SymbolCompleter : public Completer {
   public:
-    SymbolCompleter(CommandInterpreter &interpreter, const char *completion_str,
-                    int match_start_point, int max_return_elements,
-                    StringList &matches);
+    SymbolCompleter(CommandInterpreter &interpreter,
+                    llvm::StringRef completion_str, int match_start_point,
+                    int max_return_elements, StringList &matches);
 
     Searcher::Depth GetDepth() override;
 
index 6ba276e..177da60 100644 (file)
@@ -100,9 +100,10 @@ public:
 
   virtual lldb::OptionValueSP DeepCopy() const = 0;
 
-  virtual size_t AutoComplete(CommandInterpreter &interpreter, const char *s,
-                              int match_start_point, int max_return_elements,
-                              bool &word_complete, StringList &matches);
+  virtual size_t AutoComplete(CommandInterpreter &interpreter,
+                              llvm::StringRef s, int match_start_point,
+                              int max_return_elements, bool &word_complete,
+                              StringList &matches);
 
   //-----------------------------------------------------------------
   // Subclasses can override these functions
index 8a165d4..aa54812 100644 (file)
@@ -61,7 +61,7 @@ public:
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, const char *s,
+  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
                       int match_start_point, int max_return_elements,
                       bool &word_complete, StringList &matches) override;
 
index 0635907..d429c05 100644 (file)
@@ -50,7 +50,7 @@ public:
     return true;
   }
 
-  size_t AutoComplete(CommandInterpreter &interpreter, const char *s,
+  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
                       int match_start_point, int max_return_elements,
                       bool &word_complete, StringList &matches) override;
 
index 736b68e..273e69c 100644 (file)
@@ -62,7 +62,7 @@ public:
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, const char *s,
+  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
                       int match_start_point, int max_return_elements,
                       bool &word_complete, StringList &matches) override;
 
index 7569a5f..8020aa7 100644 (file)
@@ -54,7 +54,7 @@ public:
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, const char *s,
+  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
                       int match_start_point, int max_return_elements,
                       bool &word_complete, StringList &matches) override;
 
index 595bde0..472cd9e 100644 (file)
@@ -1,5 +1,4 @@
-//===-- OptionValueFormatEntity.h --------------------------------------*- C++
-//-*-===//
+//===-- OptionValueFormatEntity.h --------------------------------*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -46,7 +45,7 @@ public:
 
   lldb::OptionValueSP DeepCopy() const override;
 
-  size_t AutoComplete(CommandInterpreter &interpreter, const char *s,
+  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
                       int match_start_point, int max_return_elements,
                       bool &word_complete, StringList &matches) override;
 
index b518568..841de88 100644 (file)
@@ -61,7 +61,7 @@ public:
 
   void SetCurrentValue(const UUID &value) { m_uuid = value; }
 
-  size_t AutoComplete(CommandInterpreter &interpreter, const char *s,
+  size_t AutoComplete(CommandInterpreter &interpreter, llvm::StringRef s,
                       int match_start_point, int max_return_elements,
                       bool &word_complete, StringList &matches) override;
 
index 5ede561..24b020d 100644 (file)
@@ -1,5 +1,4 @@
-//===-- Variable.h ----------------------------------------------*- C++
-//-*-===//
+//===-- Variable.h -----------------------------------------------*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -103,8 +102,9 @@ public:
       GetVariableCallback callback, void *baton, VariableList &variable_list,
       ValueObjectList &valobj_list);
 
-  static size_t AutoComplete(const ExecutionContext &exe_ctx, const char *name,
-                             StringList &matches, bool &word_complete);
+  static size_t AutoComplete(const ExecutionContext &exe_ctx,
+                             llvm::StringRef name, StringList &matches,
+                             bool &word_complete);
 
   CompilerDeclContext GetDeclContext();
 
index 6288786..50ea7ba 100644 (file)
 
 #include "lldb/lldb-private-enumerations.h"
 
+#include "llvm/ADT/StringRef.h"
+
 namespace lldb_private {
-bool NameMatches(const char *name, NameMatchType match_type, const char *match);
+bool NameMatches(llvm::StringRef name, NameMatchType match_type,
+                 llvm::StringRef match);
 }
 
 #endif
index c07e5ae..10c1a24 100644 (file)
@@ -53,8 +53,9 @@ CommandCompletions::CommonCompletionElement
 
 bool CommandCompletions::InvokeCommonCompletionCallbacks(
     CommandInterpreter &interpreter, uint32_t completion_mask,
-    const char *completion_str, int match_start_point, int max_return_elements,
-    SearchFilter *searcher, bool &word_complete, StringList &matches) {
+    llvm::StringRef completion_str, int match_start_point,
+    int max_return_elements, SearchFilter *searcher, bool &word_complete,
+    StringList &matches) {
   bool handled = false;
 
   if (completion_mask & eCustomCompletion)
@@ -76,7 +77,7 @@ bool CommandCompletions::InvokeCommonCompletionCallbacks(
 }
 
 int CommandCompletions::SourceFiles(CommandInterpreter &interpreter,
-                                    const char *partial_file_name,
+                                    llvm::StringRef partial_file_name,
                                     int match_start_point,
                                     int max_return_elements,
                                     SearchFilter *searcher, bool &word_complete,
@@ -158,7 +159,7 @@ DiskFilesOrDirectoriesCallback(void *baton, FileSpec::FileType file_type,
   return FileSpec::eEnumerateDirectoryResultNext;
 }
 
-static int DiskFilesOrDirectories(const char *partial_file_name,
+static int DiskFilesOrDirectories(llvm::StringRef partial_file_name,
                                   bool only_directories, bool &saw_directory,
                                   StringList &matches) {
   // I'm going to  use the "glob" function with GLOB_TILDE for user directory
@@ -166,23 +167,20 @@ static int DiskFilesOrDirectories(const char *partial_file_name,
   // If it is not defined on your host system, you'll need to implement it
   // yourself...
 
-  size_t partial_name_len = strlen(partial_file_name);
+  size_t partial_name_len = partial_file_name.size();
 
   if (partial_name_len >= PATH_MAX)
     return matches.GetSize();
 
   // This copy of the string will be cut up into the directory part, and the
-  // remainder.  end_ptr
-  // below will point to the place of the remainder in this string.  Then when
-  // we've resolved the
-  // containing directory, and opened it, we'll read the directory contents and
-  // overwrite the
-  // partial_name_copy starting from end_ptr with each of the matches.  Thus we
-  // will preserve
-  // the form the user originally typed.
+  // remainder.  end_ptr below will point to the place of the remainder in this
+  // string.  Then when we've resolved the containing directory, and opened it,
+  // we'll read the directory contents and overwrite the partial_name_copy
+  // starting from end_ptr with each of the matches.  Thus we will preserve the
+  // form the user originally typed.
 
   char partial_name_copy[PATH_MAX];
-  memcpy(partial_name_copy, partial_file_name, partial_name_len);
+  memcpy(partial_name_copy, partial_file_name.data(), partial_name_len);
   partial_name_copy[partial_name_len] = '\0';
 
   // We'll need to save a copy of the remainder for comparison, which we do
@@ -280,7 +278,7 @@ static int DiskFilesOrDirectories(const char *partial_file_name,
 }
 
 int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
-                                  const char *partial_file_name,
+                                  llvm::StringRef partial_file_name,
                                   int match_start_point,
                                   int max_return_elements,
                                   SearchFilter *searcher, bool &word_complete,
@@ -292,7 +290,7 @@ int CommandCompletions::DiskFiles(CommandInterpreter &interpreter,
 }
 
 int CommandCompletions::DiskDirectories(
-    CommandInterpreter &interpreter, const char *partial_file_name,
+    CommandInterpreter &interpreter, llvm::StringRef partial_file_name,
     int match_start_point, int max_return_elements, SearchFilter *searcher,
     bool &word_complete, StringList &matches) {
   int ret_val =
@@ -302,7 +300,7 @@ int CommandCompletions::DiskDirectories(
 }
 
 int CommandCompletions::Modules(CommandInterpreter &interpreter,
-                                const char *partial_file_name,
+                                llvm::StringRef partial_file_name,
                                 int match_start_point, int max_return_elements,
                                 SearchFilter *searcher, bool &word_complete,
                                 StringList &matches) {
@@ -321,7 +319,7 @@ int CommandCompletions::Modules(CommandInterpreter &interpreter,
 }
 
 int CommandCompletions::Symbols(CommandInterpreter &interpreter,
-                                const char *partial_file_name,
+                                llvm::StringRef partial_file_name,
                                 int match_start_point, int max_return_elements,
                                 SearchFilter *searcher, bool &word_complete,
                                 StringList &matches) {
@@ -340,7 +338,7 @@ int CommandCompletions::Symbols(CommandInterpreter &interpreter,
 }
 
 int CommandCompletions::SettingsNames(
-    CommandInterpreter &interpreter, const char *partial_setting_name,
+    CommandInterpreter &interpreter, llvm::StringRef partial_setting_name,
     int match_start_point, int max_return_elements, SearchFilter *searcher,
     bool &word_complete, StringList &matches) {
   // Cache the full setting name list
@@ -365,7 +363,7 @@ int CommandCompletions::SettingsNames(
 }
 
 int CommandCompletions::PlatformPluginNames(
-    CommandInterpreter &interpreter, const char *partial_name,
+    CommandInterpreter &interpreter, llvm::StringRef partial_name,
     int match_start_point, int max_return_elements, SearchFilter *searcher,
     bool &word_complete, lldb_private::StringList &matches) {
   const uint32_t num_matches =
@@ -375,7 +373,7 @@ int CommandCompletions::PlatformPluginNames(
 }
 
 int CommandCompletions::ArchitectureNames(
-    CommandInterpreter &interpreter, const char *partial_name,
+    CommandInterpreter &interpreter, llvm::StringRef partial_name,
     int match_start_point, int max_return_elements, SearchFilter *searcher,
     bool &word_complete, lldb_private::StringList &matches) {
   const uint32_t num_matches = ArchSpec::AutoComplete(partial_name, matches);
@@ -384,7 +382,7 @@ int CommandCompletions::ArchitectureNames(
 }
 
 int CommandCompletions::VariablePath(
-    CommandInterpreter &interpreter, const char *partial_name,
+    CommandInterpreter &interpreter, llvm::StringRef partial_name,
     int match_start_point, int max_return_elements, SearchFilter *searcher,
     bool &word_complete, lldb_private::StringList &matches) {
   return Variable::AutoComplete(interpreter.GetExecutionContext(), partial_name,
@@ -392,7 +390,7 @@ int CommandCompletions::VariablePath(
 }
 
 CommandCompletions::Completer::Completer(CommandInterpreter &interpreter,
-                                         const char *completion_str,
+                                         llvm::StringRef completion_str,
                                          int match_start_point,
                                          int max_return_elements,
                                          StringList &matches)
@@ -408,8 +406,8 @@ CommandCompletions::Completer::~Completer() = default;
 
 CommandCompletions::SourceFileCompleter::SourceFileCompleter(
     CommandInterpreter &interpreter, bool include_support_files,
-    const char *completion_str, int match_start_point, int max_return_elements,
-    StringList &matches)
+    llvm::StringRef completion_str, int match_start_point,
+    int max_return_elements, StringList &matches)
     : CommandCompletions::Completer(interpreter, completion_str,
                                     match_start_point, max_return_elements,
                                     matches),
@@ -492,13 +490,13 @@ static bool regex_chars(const char comp) {
 }
 
 CommandCompletions::SymbolCompleter::SymbolCompleter(
-    CommandInterpreter &interpreter, const char *completion_str,
+    CommandInterpreter &interpreter, llvm::StringRef completion_str,
     int match_start_point, int max_return_elements, StringList &matches)
     : CommandCompletions::Completer(interpreter, completion_str,
                                     match_start_point, max_return_elements,
                                     matches) {
   std::string regex_str;
-  if (completion_str && completion_str[0]) {
+  if (!completion_str.empty()) {
     regex_str.append("^");
     regex_str.append(completion_str);
   } else {
@@ -555,7 +553,7 @@ size_t CommandCompletions::SymbolCompleter::DoCompletion(SearchFilter *filter) {
 // ModuleCompleter
 //----------------------------------------------------------------------
 CommandCompletions::ModuleCompleter::ModuleCompleter(
-    CommandInterpreter &interpreter, const char *completion_str,
+    CommandInterpreter &interpreter, llvm::StringRef completion_str,
     int match_start_point, int max_return_elements, StringList &matches)
     : CommandCompletions::Completer(interpreter, completion_str,
                                     match_start_point, max_return_elements,
index 6886fe1..cf7afb8 100644 (file)
@@ -256,8 +256,8 @@ struct ArchDefinition {
   const char *name;
 };
 
-size_t ArchSpec::AutoComplete(const char *name, StringList &matches) {
-  if (name && name[0]) {
+size_t ArchSpec::AutoComplete(llvm::StringRef name, StringList &matches) {
+  if (!name.empty()) {
     for (uint32_t i = 0; i < llvm::array_lengthof(g_core_definitions); ++i) {
       if (NameMatches(g_core_definitions[i].name, eNameMatchStartsWith, name))
         matches.AppendString(g_core_definitions[i].name);
index bd2e536..4d85c36 100644 (file)
@@ -2327,60 +2327,69 @@ static void AddMatches(const FormatEntity::Entry::Definition *def,
   }
 }
 
-size_t FormatEntity::AutoComplete(const char *s, int match_start_point,
+size_t FormatEntity::AutoComplete(llvm::StringRef str, int match_start_point,
                                   int max_return_elements, bool &word_complete,
                                   StringList &matches) {
   word_complete = false;
-  llvm::StringRef str(s + match_start_point);
+  str = str.drop_front(match_start_point);
   matches.Clear();
 
   const size_t dollar_pos = str.rfind('$');
-  if (dollar_pos != llvm::StringRef::npos) {
-    // Hitting TAB after $ at the end of the string add a "{"
-    if (dollar_pos == str.size() - 1) {
-      std::string match = str.str();
-      match.append("{");
-      matches.AppendString(std::move(match));
-    } else if (str[dollar_pos + 1] == '{') {
-      const size_t close_pos = str.find('}', dollar_pos + 2);
-      if (close_pos == llvm::StringRef::npos) {
-        const size_t format_pos = str.find('%', dollar_pos + 2);
-        if (format_pos == llvm::StringRef::npos) {
-          llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
-          if (partial_variable.empty()) {
-            // Suggest all top level entites as we are just past "${"
-            AddMatches(&g_root, str, llvm::StringRef(), matches);
-          } else {
-            // We have a partially specified variable, find it
-            llvm::StringRef remainder;
-            const FormatEntity::Entry::Definition *entry_def =
-                FindEntry(partial_variable, &g_root, remainder);
-            if (entry_def) {
-              const size_t n = entry_def->num_children;
-
-              if (remainder.empty()) {
-                // Exact match
-                if (n > 0) {
-                  // "${thread.info" <TAB>
-                  matches.AppendString(MakeMatch(str, "."));
-                } else {
-                  // "${thread.id" <TAB>
-                  matches.AppendString(MakeMatch(str, "}"));
-                  word_complete = true;
-                }
-              } else if (remainder.equals(".")) {
-                // "${thread." <TAB>
-                AddMatches(entry_def, str, llvm::StringRef(), matches);
-              } else {
-                // We have a partial match
-                // "${thre" <TAB>
-                AddMatches(entry_def, str, remainder, matches);
-              }
-            }
-          }
-        }
-      }
+  if (dollar_pos == llvm::StringRef::npos)
+    return 0;
+
+  // Hitting TAB after $ at the end of the string add a "{"
+  if (dollar_pos == str.size() - 1) {
+    std::string match = str.str();
+    match.append("{");
+    matches.AppendString(match);
+    return 1;
+  }
+
+  if (str[dollar_pos + 1] != '{')
+    return 0;
+
+  const size_t close_pos = str.find('}', dollar_pos + 2);
+  if (close_pos != llvm::StringRef::npos)
+    return 0;
+
+  const size_t format_pos = str.find('%', dollar_pos + 2);
+  if (format_pos != llvm::StringRef::npos)
+    return 0;
+
+  llvm::StringRef partial_variable(str.substr(dollar_pos + 2));
+  if (partial_variable.empty()) {
+    // Suggest all top level entites as we are just past "${"
+    AddMatches(&g_root, str, llvm::StringRef(), matches);
+    return matches.GetSize();
+  }
+
+  // We have a partially specified variable, find it
+  llvm::StringRef remainder;
+  const FormatEntity::Entry::Definition *entry_def =
+      FindEntry(partial_variable, &g_root, remainder);
+  if (!entry_def)
+    return 0;
+
+  const size_t n = entry_def->num_children;
+
+  if (remainder.empty()) {
+    // Exact match
+    if (n > 0) {
+      // "${thread.info" <TAB>
+      matches.AppendString(MakeMatch(str, "."));
+    } else {
+      // "${thread.id" <TAB>
+      matches.AppendString(MakeMatch(str, "}"));
+      word_complete = true;
     }
+  } else if (remainder.equals(".")) {
+    // "${thread." <TAB>
+    AddMatches(entry_def, str, llvm::StringRef(), matches);
+  } else {
+    // We have a partial match
+    // "${thre" <TAB>
+    AddMatches(entry_def, str, remainder, matches);
   }
   return matches.GetSize();
 }
index 67744da..b7b6b9a 100644 (file)
@@ -1355,19 +1355,20 @@ PluginManager::GetPlatformCreateCallbackForPluginName(const ConstString &name) {
   return nullptr;
 }
 
-size_t PluginManager::AutoCompletePlatformName(const char *name,
+size_t PluginManager::AutoCompletePlatformName(llvm::StringRef name,
                                                StringList &matches) {
-  if (name) {
-    std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
-    PlatformInstances &instances = GetPlatformInstances();
-    llvm::StringRef name_sref(name);
+  if (name.empty())
+    return matches.GetSize();
 
-    PlatformInstances::iterator pos, end = instances.end();
-    for (pos = instances.begin(); pos != end; ++pos) {
-      llvm::StringRef plugin_name(pos->name.GetCString());
-      if (plugin_name.startswith(name_sref))
-        matches.AppendString(plugin_name.data());
-    }
+  std::lock_guard<std::recursive_mutex> guard(GetPlatformInstancesMutex());
+  PlatformInstances &instances = GetPlatformInstances();
+  llvm::StringRef name_sref(name);
+
+  PlatformInstances::iterator pos, end = instances.end();
+  for (pos = instances.begin(); pos != end; ++pos) {
+    llvm::StringRef plugin_name(pos->name.GetCString());
+    if (plugin_name.startswith(name_sref))
+      matches.AppendString(plugin_name.data());
   }
   return matches.GetSize();
 }
index 226db21..d2c4ac6 100644 (file)
@@ -230,24 +230,25 @@ StringList &StringList::operator=(const std::vector<std::string> &rhs) {
   return *this;
 }
 
-size_t StringList::AutoComplete(const char *s, StringList &matches,
+size_t StringList::AutoComplete(llvm::StringRef s, StringList &matches,
                                 size_t &exact_idx) const {
   matches.Clear();
   exact_idx = SIZE_MAX;
-  if (s && s[0]) {
-    const size_t s_len = strlen(s);
-    const size_t num_strings = m_strings.size();
-
-    for (size_t i = 0; i < num_strings; ++i) {
-      if (m_strings[i].find(s) == 0) {
-        if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len)
-          exact_idx = matches.GetSize();
-        matches.AppendString(m_strings[i]);
-      }
-    }
-  } else {
+  if (s.empty()) {
     // No string, so it matches everything
     matches = *this;
+    return matches.GetSize();
+  }
+
+  const size_t s_len = s.size();
+  const size_t num_strings = m_strings.size();
+
+  for (size_t i = 0; i < num_strings; ++i) {
+    if (m_strings[i].find(s) == 0) {
+      if (exact_idx == SIZE_MAX && m_strings[i].size() == s_len)
+        exact_idx = matches.GetSize();
+      matches.AppendString(m_strings[i]);
+    }
   }
   return matches.GetSize();
 }
index d7d4e61..d7ebea7 100644 (file)
@@ -126,59 +126,58 @@ static inline int xdigit_to_int(char ch) {
   return ch - '0';
 }
 
-size_t UUID::DecodeUUIDBytesFromCString(const char *p, ValueType &uuid_bytes,
-                                        const char **end,
-                                        uint32_t num_uuid_bytes) {
+llvm::StringRef UUID::DecodeUUIDBytesFromString(llvm::StringRef p,
+                                                ValueType &uuid_bytes,
+                                                uint32_t num_uuid_bytes) {
+  ::memset(uuid_bytes, 0, sizeof(uuid_bytes));
   size_t uuid_byte_idx = 0;
-  if (p) {
-    while (*p) {
-      if (isxdigit(p[0]) && isxdigit(p[1])) {
-        int hi_nibble = xdigit_to_int(p[0]);
-        int lo_nibble = xdigit_to_int(p[1]);
-        // Translate the two hex nibble characters into a byte
-        uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
-
-        // Skip both hex digits
-        p += 2;
-
-        // Increment the byte that we are decoding within the UUID value
-        // and break out if we are done
-        if (++uuid_byte_idx == num_uuid_bytes)
-          break;
-      } else if (*p == '-') {
-        // Skip dashes
-        p++;
-      } else {
-        // UUID values can only consist of hex characters and '-' chars
+  while (!p.empty()) {
+    if (isxdigit(p[0]) && isxdigit(p[1])) {
+      int hi_nibble = xdigit_to_int(p[0]);
+      int lo_nibble = xdigit_to_int(p[1]);
+      // Translate the two hex nibble characters into a byte
+      uuid_bytes[uuid_byte_idx] = (hi_nibble << 4) + lo_nibble;
+
+      // Skip both hex digits
+      p = p.drop_front(2);
+
+      // Increment the byte that we are decoding within the UUID value
+      // and break out if we are done
+      if (++uuid_byte_idx == num_uuid_bytes)
         break;
-      }
+    } else if (p.front() == '-') {
+      // Skip dashes
+      p = p.drop_front();
+    } else {
+      // UUID values can only consist of hex characters and '-' chars
+      break;
     }
   }
-  if (end)
-    *end = p;
+
   // Clear trailing bytes to 0.
   for (uint32_t i = uuid_byte_idx; i < sizeof(ValueType); i++)
     uuid_bytes[i] = 0;
-  return uuid_byte_idx;
+  return p;
 }
 size_t UUID::SetFromCString(const char *cstr, uint32_t num_uuid_bytes) {
   if (cstr == NULL)
     return 0;
 
-  const char *p = cstr;
+  llvm::StringRef orig(cstr);
+  llvm::StringRef p = orig;
 
   // Skip leading whitespace characters
-  while (isspace(*p))
-    ++p;
+  p = p.ltrim();
 
-  const size_t uuid_byte_idx =
-      UUID::DecodeUUIDBytesFromCString(p, m_uuid, &p, num_uuid_bytes);
+  llvm::StringRef rest =
+      UUID::DecodeUUIDBytesFromString(p, m_uuid, num_uuid_bytes);
+  size_t bytes_decoded = p.size() - rest.size();
 
   // If we successfully decoded a UUID, return the amount of characters that
   // were consumed
-  if (uuid_byte_idx == num_uuid_bytes) {
+  if (bytes_decoded == num_uuid_bytes) {
     m_num_uuid_bytes = num_uuid_bytes;
-    return p - cstr;
+    return orig.size() - rest.size();
   }
 
   // Else return zero to indicate we were not able to parse a UUID value
index 4c6ec8e..36fcea0 100644 (file)
@@ -1023,7 +1023,7 @@ static llvm::StringRef arch_helper() {
   static StreamString g_archs_help;
   if (g_archs_help.Empty()) {
     StringList archs;
-    ArchSpec::AutoComplete(nullptr, archs);
+    ArchSpec::AutoComplete(llvm::StringRef(), archs);
     g_archs_help.Printf("These are the supported architecture names:\n");
     archs.Join("\n", g_archs_help);
   }
index bacdbc5..446fb8e 100644 (file)
@@ -573,9 +573,10 @@ bool OptionValue::DumpQualifiedName(Stream &strm) const {
   return dumped_something;
 }
 
-size_t OptionValue::AutoComplete(CommandInterpreter &interpreter, const char *s,
-                                 int match_start_point, int max_return_elements,
-                                 bool &word_complete, StringList &matches) {
+size_t OptionValue::AutoComplete(CommandInterpreter &interpreter,
+                                 llvm::StringRef s, int match_start_point,
+                                 int max_return_elements, bool &word_complete,
+                                 StringList &matches) {
   word_complete = false;
   matches.Clear();
   return matches.GetSize();
index 81d458f..3e41300 100644 (file)
@@ -74,7 +74,7 @@ lldb::OptionValueSP OptionValueArch::DeepCopy() const {
 }
 
 size_t OptionValueArch::AutoComplete(CommandInterpreter &interpreter,
-                                     const char *s, int match_start_point,
+                                     llvm::StringRef s, int match_start_point,
                                      int max_return_elements,
                                      bool &word_complete, StringList &matches) {
   word_complete = false;
index bd988fa..85799fe 100644 (file)
@@ -76,35 +76,23 @@ lldb::OptionValueSP OptionValueBoolean::DeepCopy() const {
   return OptionValueSP(new OptionValueBoolean(*this));
 }
 
-size_t OptionValueBoolean::AutoComplete(CommandInterpreter &interpreter,
-                                        const char *s, int match_start_point,
-                                        int max_return_elements,
-                                        bool &word_complete,
-                                        StringList &matches) {
+size_t OptionValueBoolean::AutoComplete(
+    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
+    int max_return_elements, bool &word_complete, StringList &matches) {
   word_complete = false;
   matches.Clear();
-  struct StringEntry {
-    const char *string;
-    const size_t length;
-  };
-  static const StringEntry g_autocomplete_entries[] = {
-      {"true", 4}, {"false", 5}, {"on", 2}, {"off", 3},
-      {"yes", 3},  {"no", 2},    {"1", 1},  {"0", 1},
-  };
-  const size_t k_num_autocomplete_entries =
-      llvm::array_lengthof(g_autocomplete_entries);
+  static const llvm::StringRef g_autocomplete_entries[] = {
+      "true", "false", "on", "off", "yes", "no", "1", "0"};
 
-  if (s && s[0]) {
-    const size_t s_len = strlen(s);
-    for (size_t i = 0; i < k_num_autocomplete_entries; ++i) {
-      if (s_len <= g_autocomplete_entries[i].length)
-        if (::strncasecmp(s, g_autocomplete_entries[i].string, s_len) == 0)
-          matches.AppendString(g_autocomplete_entries[i].string);
-    }
-  } else {
-    // only suggest "true" or "false" by default
-    for (size_t i = 0; i < 2; ++i)
-      matches.AppendString(g_autocomplete_entries[i].string);
+  auto entries = llvm::makeArrayRef(g_autocomplete_entries);
+
+  // only suggest "true" or "false" by default
+  if (s.empty())
+    entries = entries.take_front(2);
+
+  for (auto entry : entries) {
+    if (entry.startswith_lower(s))
+      matches.AppendString(entry);
   }
   return matches.GetSize();
 }
index 3ec2829..679b5cc 100644 (file)
@@ -111,13 +111,13 @@ lldb::OptionValueSP OptionValueEnumeration::DeepCopy() const {
 }
 
 size_t OptionValueEnumeration::AutoComplete(
-    CommandInterpreter &interpreter, const char *s, int match_start_point,
+    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
     int max_return_elements, bool &word_complete, StringList &matches) {
   word_complete = false;
   matches.Clear();
 
   const uint32_t num_enumerators = m_enumerations.GetSize();
-  if (s && s[0]) {
+  if (!s.empty()) {
     for (size_t i = 0; i < num_enumerators; ++i) {
       llvm::StringRef name = m_enumerations.GetCStringAtIndex(i);
       if (name.startswith(s))
index f5c292d..a6eb537 100644 (file)
@@ -101,11 +101,9 @@ lldb::OptionValueSP OptionValueFileSpec::DeepCopy() const {
   return OptionValueSP(new OptionValueFileSpec(*this));
 }
 
-size_t OptionValueFileSpec::AutoComplete(CommandInterpreter &interpreter,
-                                         const char *s, int match_start_point,
-                                         int max_return_elements,
-                                         bool &word_complete,
-                                         StringList &matches) {
+size_t OptionValueFileSpec::AutoComplete(
+    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
+    int max_return_elements, bool &word_complete, StringList &matches) {
   word_complete = false;
   matches.Clear();
   CommandCompletions::InvokeCommonCompletionCallbacks(
index 29c3b40..03f077c 100644 (file)
@@ -108,7 +108,7 @@ lldb::OptionValueSP OptionValueFormatEntity::DeepCopy() const {
 }
 
 size_t OptionValueFormatEntity::AutoComplete(
-    CommandInterpreter &interpreter, const char *s, int match_start_point,
+    CommandInterpreter &interpreter, llvm::StringRef s, int match_start_point,
     int max_return_elements, bool &word_complete, StringList &matches) {
   return FormatEntity::AutoComplete(s, match_start_point, max_return_elements,
                                     word_complete, matches);
index 1813223..bd6858c 100644 (file)
@@ -68,7 +68,7 @@ lldb::OptionValueSP OptionValueUUID::DeepCopy() const {
 }
 
 size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
-                                     const char *s, int match_start_point,
+                                     llvm::StringRef s, int match_start_point,
                                      int max_return_elements,
                                      bool &word_complete, StringList &matches) {
   word_complete = false;
@@ -79,8 +79,8 @@ size_t OptionValueUUID::AutoComplete(CommandInterpreter &interpreter,
     const size_t num_modules = target->GetImages().GetSize();
     if (num_modules > 0) {
       UUID::ValueType uuid_bytes;
-      const size_t num_bytes_decoded =
-          UUID::DecodeUUIDBytesFromCString(s, uuid_bytes, nullptr);
+      llvm::StringRef rest = UUID::DecodeUUIDBytesFromString(s, uuid_bytes);
+      const size_t num_bytes_decoded = s.size() - rest.size();
       for (size_t i = 0; i < num_modules; ++i) {
         ModuleSP module_sp(target->GetImages().GetModuleAtIndex(i));
         if (module_sp) {
index 7f799b9..43f2309 100644 (file)
@@ -1,5 +1,4 @@
-//===-- EmulateInstructionARM64.cpp -------------------------------*- C++
-//-*-===//
+//===-- EmulateInstructionARM64.cpp ------------------------------*- C++-*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
index d500395..9a99b8f 100644 (file)
@@ -31,6 +31,8 @@
 #include "lldb/Target/Target.h"
 #include "lldb/Target/Thread.h"
 
+#include "llvm/ADT/Twine.h"
+
 using namespace lldb;
 using namespace lldb_private;
 
@@ -483,24 +485,24 @@ bool Variable::DumpLocationForAddress(Stream *s, const Address &address) {
 }
 
 static void PrivateAutoComplete(
-    StackFrame *frame, const std::string &partial_path,
-    const std::string
+    StackFrame *frame, llvm::StringRef partial_path,
+    const llvm::Twine
         &prefix_path, // Anything that has been resolved already will be in here
     const CompilerType &compiler_type,
     StringList &matches, bool &word_complete);
 
 static void PrivateAutoCompleteMembers(
     StackFrame *frame, const std::string &partial_member_name,
-    const std::string &partial_path,
-    const std::string
+    llvm::StringRef partial_path,
+    const llvm::Twine
         &prefix_path, // Anything that has been resolved already will be in here
     const CompilerType &compiler_type,
     StringList &matches, bool &word_complete);
 
 static void PrivateAutoCompleteMembers(
     StackFrame *frame, const std::string &partial_member_name,
-    const std::string &partial_path,
-    const std::string
+    llvm::StringRef partial_path,
+    const llvm::Twine
         &prefix_path, // Anything that has been resolved already will be in here
     const CompilerType &compiler_type,
     StringList &matches, bool &word_complete) {
@@ -551,7 +553,7 @@ static void PrivateAutoCompleteMembers(
                                          // already will be in here
               member_compiler_type.GetCanonicalType(), matches, word_complete);
         } else {
-          matches.AppendString(prefix_path + member_name);
+          matches.AppendString((prefix_path + member_name).str());
         }
       }
     }
@@ -559,8 +561,8 @@ static void PrivateAutoCompleteMembers(
 }
 
 static void PrivateAutoComplete(
-    StackFrame *frame, const std::string &partial_path,
-    const std::string
+    StackFrame *frame, llvm::StringRef partial_path,
+    const llvm::Twine
         &prefix_path, // Anything that has been resolved already will be in here
     const CompilerType &compiler_type,
     StringList &matches, bool &word_complete) {
@@ -584,15 +586,15 @@ static void PrivateAutoComplete(
       case eTypeClassReference:
       case eTypeClassTypedef:
       case eTypeClassVector: {
-        matches.AppendString(prefix_path);
+        matches.AppendString(prefix_path.str());
         word_complete = matches.GetSize() == 1;
       } break;
 
       case eTypeClassClass:
       case eTypeClassStruct:
       case eTypeClassUnion:
-        if (prefix_path.back() != '.')
-          matches.AppendString(prefix_path + '.');
+        if (prefix_path.str().back() != '.')
+          matches.AppendString((prefix_path + ".").str());
         break;
 
       case eTypeClassObjCObject:
@@ -602,9 +604,9 @@ static void PrivateAutoComplete(
       case eTypeClassPointer: {
         bool omit_empty_base_classes = true;
         if (compiler_type.GetNumChildren(omit_empty_base_classes) > 0)
-          matches.AppendString(prefix_path + "->");
+          matches.AppendString((prefix_path + "->").str());
         else {
-          matches.AppendString(prefix_path);
+          matches.AppendString(prefix_path.str());
           word_complete = true;
         }
       } break;
@@ -628,21 +630,21 @@ static void PrivateAutoComplete(
     const char ch = partial_path[0];
     switch (ch) {
     case '*':
-      if (prefix_path.empty()) {
-        PrivateAutoComplete(frame, partial_path.substr(1), std::string("*"),
-                            compiler_type, matches, word_complete);
+      if (prefix_path.str().empty()) {
+        PrivateAutoComplete(frame, partial_path.substr(1), "*", compiler_type,
+                            matches, word_complete);
       }
       break;
 
     case '&':
-      if (prefix_path.empty()) {
+      if (prefix_path.isTriviallyEmpty()) {
         PrivateAutoComplete(frame, partial_path.substr(1), std::string("&"),
                             compiler_type, matches, word_complete);
       }
       break;
 
     case '-':
-      if (partial_path[1] == '>' && !prefix_path.empty()) {
+      if (partial_path[1] == '>' && !prefix_path.str().empty()) {
         switch (type_class) {
         case lldb::eTypeClassPointer: {
           CompilerType pointee_type(compiler_type.GetPointeeType());
@@ -739,10 +741,10 @@ static void PrivateAutoComplete(
                       variable_compiler_type.GetCanonicalType(), matches,
                       word_complete);
                 } else {
-                  matches.AppendString(prefix_path + variable_name);
+                  matches.AppendString((prefix_path + variable_name).str());
                 }
               } else if (remaining_partial_path.empty()) {
-                matches.AppendString(prefix_path + variable_name);
+                matches.AppendString((prefix_path + variable_name).str());
               }
             }
           }
@@ -754,17 +756,13 @@ static void PrivateAutoComplete(
 }
 
 size_t Variable::AutoComplete(const ExecutionContext &exe_ctx,
-                              const char *partial_path_cstr,
-                              StringList &matches, bool &word_complete) {
+                              llvm::StringRef partial_path, StringList &matches,
+                              bool &word_complete) {
   word_complete = false;
-  std::string partial_path;
-  std::string prefix_path;
   CompilerType compiler_type;
-  if (partial_path_cstr && partial_path_cstr[0])
-    partial_path = partial_path_cstr;
 
-  PrivateAutoComplete(exe_ctx.GetFramePtr(), partial_path, prefix_path,
-                      compiler_type, matches, word_complete);
+  PrivateAutoComplete(exe_ctx.GetFramePtr(), partial_path, "", compiler_type,
+                      matches, word_complete);
 
   return matches.GetSize();
 }
index a15ab4b..7b733d2 100644 (file)
 
 using namespace lldb_private;
 
-bool lldb_private::NameMatches(const char *name, NameMatchType match_type,
-                               const char *match) {
+bool lldb_private::NameMatches(llvm::StringRef name, NameMatchType match_type,
+                               llvm::StringRef match) {
   if (match_type == eNameMatchIgnore)
     return true;
 
   if (name == match)
     return true;
 
-  if (name && match) {
-    llvm::StringRef name_sref(name);
-    llvm::StringRef match_sref(match);
-    switch (match_type) {
-    case eNameMatchIgnore: // This case cannot occur: tested before
-      return true;
-    case eNameMatchEquals:
-      return name_sref == match_sref;
-    case eNameMatchContains:
-      return name_sref.find(match_sref) != llvm::StringRef::npos;
-    case eNameMatchStartsWith:
-      return name_sref.startswith(match_sref);
-    case eNameMatchEndsWith:
-      return name_sref.endswith(match_sref);
-    case eNameMatchRegularExpression: {
-      RegularExpression regex(match_sref);
-      return regex.Execute(name_sref);
-    } break;
-    }
+  if (name.empty() || match.empty())
+    return false;
+
+  switch (match_type) {
+  case eNameMatchIgnore: // This case cannot occur: tested before
+    return true;
+  case eNameMatchEquals:
+    return name == match;
+  case eNameMatchContains:
+    return name.contains(match);
+  case eNameMatchStartsWith:
+    return name.startswith(match);
+  case eNameMatchEndsWith:
+    return name.endswith(match);
+  case eNameMatchRegularExpression: {
+    RegularExpression regex(match);
+    return regex.Execute(name);
+  } break;
   }
   return false;
 }