<rdar://problem/12437929>

Providing a special mode of operator for "memory read -f c-str" which actually works in most common cases
Where the old behavior would provide:
(lldb) mem read --format s `foo`
0x100000f5d: NULL

Now we do:
(lldb) mem read --format s `foo`
0x100000f5d: "hello world"

You can also specify a count and that many strings will be showed starting at the initial address:
(lldb) mem read -c 2 -f c-str `foo`
0x100000f1d: "hello world"
0x100000f29: "short"



git-svn-id: https://llvm.org/svn/llvm-project/lldb/trunk@173076 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectMemory.cpp b/source/Commands/CommandObjectMemory.cpp
index 947fc27..cbff45c 100644
--- a/source/Commands/CommandObjectMemory.cpp
+++ b/source/Commands/CommandObjectMemory.cpp
@@ -586,7 +586,7 @@
         }
 
         size_t item_count = m_format_options.GetCountValue().GetCurrentValue();
-        const size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+        size_t item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
         const size_t num_per_line = m_memory_options.m_num_per_line.GetCurrentValue();
 
         if (total_byte_size == 0)
@@ -641,6 +641,8 @@
             return false;
         }
         
+        
+        
         DataBufferSP data_sp;
         size_t bytes_read = 0;
         if (clang_ast_type.GetOpaqueQualType())
@@ -651,7 +653,7 @@
 
             bytes_read = clang_ast_type.GetTypeByteSize() * m_format_options.GetCountValue().GetCurrentValue();
         }
-        else
+        else if (m_format_options.GetFormatValue().GetCurrentValue() != eFormatCString)
         {
             data_sp.reset (new DataBufferHeap (total_byte_size, '\0'));
             Address address(addr, NULL);
@@ -674,6 +676,46 @@
             if (bytes_read < total_byte_size)
                 result.AppendWarningWithFormat("Not all bytes (%lu/%lu) were able to be read from 0x%" PRIx64 ".", bytes_read, total_byte_size, addr);
         }
+        else
+        {
+            // we treat c-strings as a special case because they do not have a fixed size
+            if (m_format_options.GetByteSizeValue().OptionWasSet() && !m_format_options.HasGDBFormat())
+                item_byte_size = m_format_options.GetByteSizeValue().GetCurrentValue();
+            else
+                item_byte_size = target->GetMaximumSizeOfStringSummary();
+            if (!m_format_options.GetCountValue().OptionWasSet())
+                item_count = 1;
+            data_sp.reset (new DataBufferHeap ((item_byte_size+1) * item_count, '\0')); // account for NULLs as necessary
+            uint8_t *data_ptr = data_sp->GetBytes();
+            auto data_addr = addr;
+            auto count = item_count;
+            item_count = 0;
+            while (item_count < count)
+            {
+                std::string buffer;
+                buffer.resize(item_byte_size+1,0);
+                Error error;
+                size_t read = target->ReadCStringFromMemory(data_addr, &buffer[0], item_byte_size+1, error);
+                if (error.Fail())
+                {
+                    result.AppendErrorWithFormat("failed to read memory from 0x%" PRIx64 ".\n", addr);
+                    result.SetStatus(eReturnStatusFailed);
+                    return false;
+                }
+                if (item_byte_size == read)
+                {
+                    result.AppendWarningWithFormat("unable to find a NULL terminated string at 0x%" PRIx64 ".Consider increasing the maximum read length.\n", data_addr);
+                    break;
+                }
+                read+=1; // account for final NULL byte
+                memcpy(data_ptr, &buffer[0], read);
+                data_ptr += read;
+                data_addr += read;
+                bytes_read += read;
+                item_count++; // if we break early we know we only read item_count strings
+            }
+            data_sp.reset(new DataBufferHeap(data_sp->GetBytes(),bytes_read+1));
+        }
 
         m_next_addr = addr + bytes_read;
         m_prev_byte_size = bytes_read;