Initial checkin of lldb code from internal Apple repo.


git-svn-id: https://llvm.org/svn/llvm-project/llvdb/trunk@105619 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/source/Commands/CommandObjectSourceFile.cpp b/source/Commands/CommandObjectSourceFile.cpp
new file mode 100644
index 0000000..df70bc9
--- /dev/null
+++ b/source/Commands/CommandObjectSourceFile.cpp
@@ -0,0 +1,206 @@
+//===-- CommandObjectSourceFile.cpp -----------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+
+#include "CommandObjectSourceFile.h"
+
+// C Includes
+// C++ Includes
+// Other libraries and framework includes
+// Project includes
+#include "lldb/Core/Args.h"
+#include "lldb/Interpreter/CommandContext.h"
+#include "lldb/Interpreter/CommandInterpreter.h"
+#include "lldb/Interpreter/CommandReturnObject.h"
+#include "lldb/Target/Process.h"
+#include "lldb/Core/SourceManager.h"
+#include "lldb/Target/TargetList.h"
+#include "lldb/Interpreter/CommandCompletions.h"
+
+using namespace lldb;
+using namespace lldb_private;
+
+CommandObjectSourceFile::CommandOptions::CommandOptions () :
+    Options()
+{
+}
+
+CommandObjectSourceFile::CommandOptions::~CommandOptions ()
+{
+}
+
+Error
+CommandObjectSourceFile::CommandOptions::SetOptionValue (int option_idx, const char *option_arg)
+{
+    Error error;
+    const char short_option = g_option_table[option_idx].short_option;
+    switch (short_option)
+    {
+    case 'l':
+        start_line = Args::StringToUInt32 (option_arg, 0);
+        if (start_line == 0)
+            error.SetErrorStringWithFormat("Invalid line number: '%s'.\n", option_arg);
+        break;
+
+    case 'n':
+        num_lines = Args::StringToUInt32 (option_arg, 0);
+        if (num_lines == 0)
+            error.SetErrorStringWithFormat("Invalid line count: '%s'.\n", option_arg);
+        break;
+
+     case 'f':
+        file_name = option_arg;
+        break;
+
+   default:
+        error.SetErrorStringWithFormat("Unrecognized short option '%c'.\n", short_option);
+        break;
+    }
+
+    return error;
+}
+
+void
+CommandObjectSourceFile::CommandOptions::ResetOptionValues ()
+{
+    Options::ResetOptionValues();
+
+    file_spec.Clear();
+    file_name.clear();
+    start_line = 0;
+    num_lines = 10;
+}
+
+const lldb::OptionDefinition*
+CommandObjectSourceFile::CommandOptions::GetDefinitions ()
+{
+    return g_option_table;
+}
+
+lldb::OptionDefinition
+CommandObjectSourceFile::CommandOptions::g_option_table[] =
+{
+{ 0, false, "line",       'l', required_argument, NULL, 0, "<line>",    "The line number at which to start the display source."},
+{ 0, false, "file",       'f', required_argument, NULL, CommandCompletions::eSourceFileCompletion, "<file>",    "The file from which to display source."},
+{ 0, false, "count",      'n', required_argument, NULL, 0, "<count>",   "The number of source lines to display."},
+{ 0, false, NULL, 0, 0, NULL, 0, NULL, NULL }
+};
+
+
+
+//-------------------------------------------------------------------------
+// CommandObjectSourceFile
+//-------------------------------------------------------------------------
+
+CommandObjectSourceFile::CommandObjectSourceFile() :
+    CommandObject ("source-file",
+                     "Display source files from the current executable's debug info.",
+                     "source-file [<cmd-options>] [<filename>]")
+{
+}
+
+CommandObjectSourceFile::~CommandObjectSourceFile ()
+{
+}
+
+
+Options *
+CommandObjectSourceFile::GetOptions ()
+{
+    return &m_options;
+}
+
+
+bool
+CommandObjectSourceFile::Execute
+(
+    Args& args,
+    CommandContext *context,
+    CommandInterpreter *interpreter,
+    CommandReturnObject &result
+)
+{
+    const int argc = args.GetArgumentCount();
+
+    if (argc != 0)
+    {
+        result.AppendErrorWithFormat("'%s' takes no arguments, only flags.\n", GetCommandName());
+        result.SetStatus (eReturnStatusFailed);
+    }
+
+    ExecutionContext exe_ctx(context->GetExecutionContext());
+    if (m_options.file_name.empty())
+    {
+        // Last valid source manager context, or the current frame if no
+        // valid last context in source manager.
+        // One little trick here, if you type the exact same list command twice in a row, it is
+        // more likely because you typed it once, then typed it again
+        if (m_options.start_line == 0)
+        {
+            if (interpreter->GetSourceManager().DisplayMoreWithLineNumbers (&result.GetOutputStream()))
+            {
+                result.SetStatus (eReturnStatusSuccessFinishResult);
+            }
+        }
+        else
+        {
+            if (interpreter->GetSourceManager().DisplaySourceLinesWithLineNumbersUsingLastFile(
+                        m_options.start_line,   // Line to display
+                        0,                      // Lines before line to display
+                        m_options.num_lines,    // Lines after line to display
+                        "",                     // Don't mark "line"
+                        &result.GetOutputStream()))
+            {
+                result.SetStatus (eReturnStatusSuccessFinishResult);
+            }
+
+        }
+    }
+    else
+    {
+        const char *filename = m_options.file_name.c_str();
+        Target *target = context->GetTarget();
+        if (target == NULL)
+        {
+            result.AppendError ("invalid target, set executable file using 'file' command");
+            result.SetStatus (eReturnStatusFailed);
+            return false;
+        }
+
+
+        bool check_inlines = false;
+        SymbolContextList sc_list;
+        size_t num_matches = target->GetImages().ResolveSymbolContextForFilePath (filename,
+                                                                                  0,
+                                                                                  check_inlines,
+                                                                                  eSymbolContextModule | eSymbolContextCompUnit,
+                                                                                  sc_list);
+        if (num_matches > 0)
+        {
+            SymbolContext sc;
+            if (sc_list.GetContextAtIndex(0, sc))
+            {
+                if (sc.comp_unit)
+                {
+                    interpreter->GetSourceManager ().DisplaySourceLinesWithLineNumbers (sc.comp_unit,
+                                                                                        m_options.start_line,   // Line to display
+                                                                                        0,                      // Lines before line to display
+                                                                                        m_options.num_lines,    // Lines after line to display
+                                                                                        "",                     // Don't mark "line"
+                                                                                        &result.GetOutputStream());
+
+                    result.SetStatus (eReturnStatusSuccessFinishResult);
+
+                }
+            }
+        }
+    }
+
+    return result.Succeeded();
+}
+