Fixed a hang which causes LLDB to enter an infinite
loop if "memory read" is run with the -t option and
the type name contains a keyword like "struct" that
isn't followed by a space.  Now if a keyword isn't
followed by a space we continue searching after it,
instead of at the beginning of the type name.

Also optimized the code to not call strlen() on
a fixed set of statically-declared constant strings.


git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@160016 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 61bf149..1760c1d 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -398,19 +398,52 @@
             uint32_t reference_count = 0;
             uint32_t pointer_count = 0;
             size_t idx;
-            static const char *g_keywords[] = { "const", "volatile", "restrict", "struct", "class", "union"};
-            static size_t g_num_keywords = sizeof(g_keywords)/sizeof(const char *);
+            
+#define ALL_KEYWORDS        \
+    KEYWORD("const")        \
+    KEYWORD("volatile")     \
+    KEYWORD("restrict")     \
+    KEYWORD("struct")       \
+    KEYWORD("class")        \
+    KEYWORD("union")
+            
+#define KEYWORD(s) s,
+            static const char *g_keywords[] =
+            {
+                ALL_KEYWORDS
+            };
+#undef KEYWORD
+
+#define KEYWORD(s) (sizeof(s) - 1),
+            static const int g_keyword_lengths[] =
+            {
+                ALL_KEYWORDS
+            };
+#undef KEYWORD
+            
+#undef ALL_KEYWORDS
+            
+            static size_t g_num_keywords = sizeof(g_keywords) / sizeof(const char *);
             std::string type_str(view_as_type_cstr);
             
             // Remove all instances of g_keywords that are followed by spaces
             for (size_t i = 0; i < g_num_keywords; ++i)
             {
                 const char *keyword = g_keywords[i];
-                int keyword_len = ::strlen (keyword);
-                while ((idx = type_str.find (keyword)) != std::string::npos)
+                int keyword_len = g_keyword_lengths[i];
+                
+                idx = 0;
+                while ((idx = type_str.find (keyword, idx)) != std::string::npos)
                 {
                     if (type_str[idx + keyword_len] == ' ' || type_str[idx + keyword_len] == '\t')
+                    {
                         type_str.erase(idx, keyword_len+1);
+                        idx = 0;
+                    }
+                    else
+                    {
+                        idx += keyword_len;
+                    }
                 }
             }
             bool done = type_str.empty();