[haiku-commits] haiku: hrev44364 - src/apps/debugger/user_interface/cli src/kits/shared headers/private/shared src/apps/debugger

  • From: ingo_weinhold@xxxxxx
  • To: haiku-commits@xxxxxxxxxxxxx
  • Date: Fri, 20 Jul 2012 23:34:29 +0200 (CEST)

hrev44364 adds 3 changesets to branch 'master'
old head: fc4d98a2c09fcc8e96eda3f9a234ae9cd71dba48
new head: 6d60b554e6d6cee2a7e73e95b5e06374c9f2e32f

----------------------------------------------------------------------------

af350aa: Add private shared class ArgumentVector
  
  The parser is based on the FS shell's ArgVector.

0f1f968: Debugger: Actually create the CLI, if requested

6d60b55: Debugger: Some basic work to get the CLI going
  
  There's an input loop thread which reads and parses command lines and
  the infrastructure for registering and executing commands. Currently
  only "help" and "quit" commands are implemented.

                                    [ Ingo Weinhold <ingo_weinhold@xxxxxx> ]

----------------------------------------------------------------------------

10 files changed, 607 insertions(+), 21 deletions(-)
headers/private/shared/ArgumentVector.h            |   53 ++++
src/apps/debugger/Debugger.cpp                     |   27 +-
src/apps/debugger/Jamfile                          |    7 +-
.../debugger/user_interface/cli/CliCommand.cpp     |   20 ++
src/apps/debugger/user_interface/cli/CliCommand.h  |   33 +++
src/apps/debugger/user_interface/cli/CliContext.h  |   13 +
.../cli/CommandLineUserInterface.cpp               |  236 +++++++++++++++-
.../user_interface/cli/CommandLineUserInterface.h  |   35 +++
src/kits/shared/ArgumentVector.cpp                 |  203 +++++++++++++
src/kits/shared/Jamfile                            |    1 +

############################################################################

Commit:      af350aa21891c6d37934df7686e2cba1d0f4f29f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=af350aa
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Fri Jul 20 21:24:33 2012 UTC

Add private shared class ArgumentVector

The parser is based on the FS shell's ArgVector.

----------------------------------------------------------------------------

diff --git a/headers/private/shared/ArgumentVector.h 
b/headers/private/shared/ArgumentVector.h
new file mode 100644
index 0000000..0b32a87
--- /dev/null
+++ b/headers/private/shared/ArgumentVector.h
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2007-2012, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef _ARGUMENT_VECTOR_H
+#define _ARGUMENT_VECTOR_H
+
+
+#include <SupportDefs.h>
+
+
+namespace BPrivate {
+
+
+class ArgumentVector {
+public:
+       enum ParseError {
+               NO_ERROR,
+               NO_MEMORY,
+               UNTERMINATED_QUOTED_STRING,
+               TRAILING_BACKSPACE
+       };
+
+public:
+                                                               
ArgumentVector();
+                                                               
~ArgumentVector();
+
+                       int32                           ArgumentCount() const   
{ return fCount; }
+                       const char* const*      Arguments() const               
{ return fArguments; }
+
+                       char**                          DetachArguments();
+                               // Caller must free() -- it's all one big 
allocation at the
+                               // returned pointer.
+
+                       ParseError                      Parse(const char* 
commandLine,
+                                                                       const 
char** _errorLocation = NULL);
+
+private:
+                       struct Parser;
+
+private:
+                       char**                          fArguments;
+                       int32                           fCount;
+};
+
+
+} // namespace BPrivate
+
+
+using BPrivate::ArgumentVector;
+
+
+#endif // _ARGUMENT_VECTOR_H
diff --git a/src/kits/shared/ArgumentVector.cpp 
b/src/kits/shared/ArgumentVector.cpp
new file mode 100644
index 0000000..c678f5d
--- /dev/null
+++ b/src/kits/shared/ArgumentVector.cpp
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2007-2012, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include <ArgumentVector.h>
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <string>
+#include <vector>
+
+
+struct ArgumentVector::Parser {
+       ParseError Parse(const char* commandLine, const char*& _errorLocation)
+       {
+               // init temporary arg/argv storage
+               fCurrentArg.clear();
+               fCurrentArgStarted = false;
+               fArgVector.clear();
+               fTotalStringSize = 0;
+
+               for (; *commandLine; commandLine++) {
+                       char c = *commandLine;
+
+                       // whitespace delimits args and is otherwise ignored
+                       if (isspace(c)) {
+                               _PushCurrentArg();
+                               continue;
+                       }
+
+                       const char* errorBase = commandLine;
+
+                       switch (c) {
+                               case '\'':
+                                       // quoted string -- no quoting
+                                       while (*++commandLine != '\'') {
+                                               c = *commandLine;
+                                               if (c == '\0') {
+                                                       _errorLocation = 
errorBase;
+                                                       return 
UNTERMINATED_QUOTED_STRING;
+                                               }
+                                               _PushCharacter(c);
+                                       }
+                                       break;
+
+                               case '"':
+                                       // quoted string -- some quoting
+                                       while (*++commandLine != '"') {
+                                               c = *commandLine;
+                                               if (c == '\0') {
+                                                       _errorLocation = 
errorBase;
+                                                       return 
UNTERMINATED_QUOTED_STRING;
+                                               }
+
+                                               if (c == '\\') {
+                                                       c = *++commandLine;
+                                                       if (c == '\0') {
+                                                               _errorLocation 
= errorBase;
+                                                               return 
UNTERMINATED_QUOTED_STRING;
+                                                       }
+
+                                                       // only '\' and '"' can 
be quoted, otherwise the
+                                                       // the '\' is treated 
as a normal char
+                                                       if (c != '\\' && c != 
'"')
+                                                               
_PushCharacter('\\');
+                                               }
+
+                                               _PushCharacter(c);
+                                       }
+                                       break;
+
+                               case '\\':
+                                       // quoted char
+                                       c = *++commandLine;
+                                       if (c == '\0') {
+                                               _errorLocation = errorBase;
+                                               return TRAILING_BACKSPACE;
+                                       }
+                                       _PushCharacter(c);
+                                       break;
+
+                               default:
+                                       // normal char
+                                       _PushCharacter(c);
+                                       break;
+                       }
+               }
+
+               // commit last arg
+               _PushCurrentArg();
+
+               return NO_ERROR;
+       }
+
+       const std::vector<std::string>& ArgVector() const
+       {
+               return fArgVector;
+       }
+
+       size_t TotalStringSize() const
+       {
+               return fTotalStringSize;
+       }
+
+private:
+       void _PushCurrentArg()
+       {
+               if (fCurrentArgStarted) {
+                       fArgVector.push_back(fCurrentArg);
+                       fTotalStringSize += fCurrentArg.length() + 1;
+                       fCurrentArgStarted = false;
+               }
+       }
+
+       void _PushCharacter(char c)
+       {
+               if (!fCurrentArgStarted) {
+                       fCurrentArg = "";
+                       fCurrentArgStarted = true;
+               }
+
+               fCurrentArg += c;
+       }
+
+private:
+       // temporaries
+       std::string                                     fCurrentArg;
+       bool                                            fCurrentArgStarted;
+       std::vector<std::string>        fArgVector;
+       size_t                                          fTotalStringSize;
+};
+
+
+ArgumentVector::ArgumentVector()
+       :
+       fArguments(NULL),
+       fCount(0)
+{
+}
+
+
+ArgumentVector::~ArgumentVector()
+{
+       free(fArguments);
+}
+
+
+char**
+ArgumentVector::DetachArguments()
+{
+       char** arguments = fArguments;
+       fArguments = NULL;
+       fCount = 0;
+       return arguments;
+}
+
+
+ArgumentVector::ParseError
+ArgumentVector::Parse(const char* commandLine, const char** _errorLocation)
+{
+       free(DetachArguments());
+
+       ParseError error;
+       const char* errorLocation = commandLine;
+
+       try {
+               Parser parser;
+               error = parser.Parse(commandLine, errorLocation);
+
+               if (error == NO_ERROR) {
+                       // Create a char* array and copy everything into a 
single
+                       // allocation.
+                       int count = parser.ArgVector().size();
+                       size_t arraySize = (count + 1) * sizeof(char*);
+                       fArguments = (char**)malloc(
+                               arraySize + parser.TotalStringSize());
+                       if (fArguments != 0) {
+                               char* argument = (char*)(fArguments + count + 
1);
+                               for (int i = 0; i < count; i++) {
+                                       fArguments[i] = argument;
+                                       const std::string& sourceArgument = 
parser.ArgVector()[i];
+                                       size_t argumentSize = 
sourceArgument.length() + 1;
+                                       memcpy(argument, 
sourceArgument.c_str(), argumentSize);
+                                       argument += argumentSize;
+                               }
+
+                               fArguments[count] = NULL;
+                               fCount = count;
+                       } else
+                               error = NO_MEMORY;
+               }
+       } catch (...) {
+               error = NO_MEMORY;
+       }
+
+       if (error != NO_ERROR && _errorLocation != NULL)
+               *_errorLocation = errorLocation;
+
+       return error;
+}
diff --git a/src/kits/shared/Jamfile b/src/kits/shared/Jamfile
index d56a8b6..8992caa 100644
--- a/src/kits/shared/Jamfile
+++ b/src/kits/shared/Jamfile
@@ -15,6 +15,7 @@ UsePrivateHeaders kernel libroot ;
 StaticLibrary libshared.a :
        AboutMenuItem.cpp
        AboutWindow.cpp
+       ArgumentVector.cpp
        CalendarView.cpp
        ColorQuantizer.cpp
        CommandPipe.cpp

############################################################################

Commit:      0f1f968ffb6f4b19193ccad1a4edae9e9a46ab19
URL:         http://cgit.haiku-os.org/haiku/commit/?id=0f1f968
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Fri Jul 20 21:26:14 2012 UTC

Debugger: Actually create the CLI, if requested

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Debugger.cpp b/src/apps/debugger/Debugger.cpp
index c7a687c..f561747 100644
--- a/src/apps/debugger/Debugger.cpp
+++ b/src/apps/debugger/Debugger.cpp
@@ -56,7 +56,7 @@ static const char* kUsage =
        "\n"
        "Options:\n"
        "  -h, --help    - Print this usage info and exit.\n"
-       "  -c, --cli     - Use command line user interface (not yet 
implemented)\n"
+       "  -c, --cli     - Use command line user interface\n"
 ;
 
 
@@ -397,7 +397,8 @@ Debugger::ArgvReceived(int32 argc, char** argv)
                return;
        }
 
-       start_team_debugger(team, &fSettingsManager, this, thread, stopInMain);
+       start_team_debugger(team, &fSettingsManager, this, thread, stopInMain,
+               options.useCLI);
 }
 
 
@@ -481,6 +482,7 @@ Debugger::_FindTeamDebugger(team_id teamID) const
 
 // #pragma mark -
 
+
 int
 main(int argc, const char* const* argv)
 {
@@ -493,20 +495,15 @@ main(int argc, const char* const* argv)
        Options options;
        parse_arguments(argc, argv, false, options);
 
-       if (options.useCLI) {
-               // TODO: implement
-               fprintf(stderr, "Error: Command line interface 
unimplemented\n");
+       Debugger app;
+       status_t error = app.Init();
+       if (error != B_OK) {
+               fprintf(stderr, "Error: Failed to init application: %s\n",
+                       strerror(error));
                return 1;
-       } else {
-               Debugger app;
-               status_t error = app.Init();
-               if (error != B_OK) {
-                       fprintf(stderr, "Error: Failed to init application: 
%s\n",
-                               strerror(error));
-                       return 1;
-               }
-
-               app.Run();
        }
+
+       app.Run();
+
        return 0;
 }

############################################################################

Revision:    hrev44364
Commit:      6d60b554e6d6cee2a7e73e95b5e06374c9f2e32f
URL:         http://cgit.haiku-os.org/haiku/commit/?id=6d60b55
Author:      Ingo Weinhold <ingo_weinhold@xxxxxx>
Date:        Fri Jul 20 21:30:34 2012 UTC

Debugger: Some basic work to get the CLI going

There's an input loop thread which reads and parses command lines and
the infrastructure for registering and executing commands. Currently
only "help" and "quit" commands are implemented.

----------------------------------------------------------------------------

diff --git a/src/apps/debugger/Jamfile b/src/apps/debugger/Jamfile
index 193bc20..80c98fe 100644
--- a/src/apps/debugger/Jamfile
+++ b/src/apps/debugger/Jamfile
@@ -169,12 +169,13 @@ Application Debugger :
        # user_interface
        UserInterface.cpp
 
-       # user_interface/gui
-       GraphicalUserInterface.cpp
-
        # user_interface/cli
+       CliCommand.cpp
        CommandLineUserInterface.cpp
 
+       # user_interface/gui
+       GraphicalUserInterface.cpp
+
        # user_interface/gui/model
        VariablesViewState.cpp
        VariablesViewStateHistory.cpp
diff --git a/src/apps/debugger/user_interface/cli/CliCommand.cpp 
b/src/apps/debugger/user_interface/cli/CliCommand.cpp
new file mode 100644
index 0000000..c83c8cf
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliCommand.cpp
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+
+
+#include "CliCommand.h"
+
+
+CliCommand::CliCommand(const char* summary, const char* usage)
+       :
+       fSummary(summary),
+       fUsage(usage)
+{
+}
+
+
+CliCommand::~CliCommand()
+{
+}
diff --git a/src/apps/debugger/user_interface/cli/CliCommand.h 
b/src/apps/debugger/user_interface/cli/CliCommand.h
new file mode 100644
index 0000000..2a65e19
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliCommand.h
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef CLI_COMMAND_H
+#define CLI_COMMAND_H
+
+
+#include <Referenceable.h>
+
+
+class CliContext;
+
+
+class CliCommand : public BReferenceable {
+public:
+                                                               
CliCommand(const char* summary,
+                                                                       const 
char* usage);
+       virtual                                         ~CliCommand();
+
+                       const char*                     Summary() const { 
return fSummary; }
+                       const char*                     Usage() const   { 
return fUsage; }
+
+       virtual void                            Execute(int argc, const char* 
const* argv,
+                                                                       
CliContext& context) = 0;
+
+private:
+                       const char*                     fSummary;
+                       const char*                     fUsage;
+};
+
+
+#endif // CLI_COMMAND_H
diff --git a/src/apps/debugger/user_interface/cli/CliContext.h 
b/src/apps/debugger/user_interface/cli/CliContext.h
new file mode 100644
index 0000000..df31816
--- /dev/null
+++ b/src/apps/debugger/user_interface/cli/CliContext.h
@@ -0,0 +1,13 @@
+/*
+ * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxxx
+ * Distributed under the terms of the MIT License.
+ */
+#ifndef CLI_CONTEXT_H
+#define CLI_CONTEXT_H
+
+
+class CliContext {
+};
+
+
+#endif // CLI_CONTEXT_H
diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp 
b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
index 95fd5f2..ab53011 100644
--- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
+++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.cpp
@@ -1,13 +1,106 @@
 /*
  * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxxx
  * Distributed under the terms of the MIT License.
  */
 
 
 #include "CommandLineUserInterface.h"
 
+#include <stdio.h>
+
+#include <algorithm>
+
+#include <ArgumentVector.h>
+#include <Referenceable.h>
+
+#include "CliCommand.h"
+#include "CliContext.h"
+
+
+// #pragma mark - CommandEntry
+
+
+struct CommandLineUserInterface::CommandEntry {
+       CommandEntry(const BString& name, CliCommand* command)
+               :
+               fName(name),
+               fCommand(command)
+       {
+       }
+
+       const BString& Name() const
+       {
+               return fName;
+       }
+
+       CliCommand* Command() const
+       {
+               return fCommand.Get();
+       }
+
+private:
+       BString                                 fName;
+       BReference<CliCommand>  fCommand;
+};
+
+
+// #pragma mark - HelpCommand
+
+
+struct CommandLineUserInterface::HelpCommand : CliCommand {
+       HelpCommand(CommandLineUserInterface* userInterface)
+               :
+               CliCommand("print a list of all commands",
+                       "%s\n"
+                       "Prints a list of all commands."),
+               fUserInterface(userInterface)
+       {
+       }
+
+       virtual void Execute(int argc, const char* const* argv, CliContext& 
context)
+       {
+               fUserInterface->_PrintHelp();
+       }
+
+private:
+       CommandLineUserInterface* fUserInterface;
+};
+
+
+// #pragma mark - HelpCommand
+
+
+struct CommandLineUserInterface::QuitCommand : CliCommand {
+       QuitCommand(CommandLineUserInterface* userInterface)
+               :
+               CliCommand("quit Debugger",
+                       "%s\n"
+                       "Quits Debugger."),
+               fUserInterface(userInterface)
+       {
+       }
+
+       virtual void Execute(int argc, const char* const* argv, CliContext& 
context)
+       {
+               fUserInterface->fListener->UserInterfaceQuitRequested();
+       }
+
+private:
+       CommandLineUserInterface* fUserInterface;
+};
+
+
+// #pragma mark - CommandLineUserInterface
+
 
 CommandLineUserInterface::CommandLineUserInterface()
+       :
+       fThread(-1),
+       fTeam(NULL),
+       fListener(NULL),
+       fCommands(20, true),
+       fTerminating(false)
 {
 }
 
@@ -27,33 +120,48 @@ CommandLineUserInterface::ID() const
 status_t
 CommandLineUserInterface::Init(Team* team, UserInterfaceListener* listener)
 {
-       return B_UNSUPPORTED;
+       fTeam = team;
+       fListener = listener;
+
+       status_t error = _RegisterCommands();
+       if (error != B_OK)
+               return error;
+
+       fThread = spawn_thread(&_InputLoopEntry, "CLI", B_NORMAL_PRIORITY, 
this);
+       if (fThread < 0)
+               return fThread;
+
+       return B_OK;
 }
 
 
 void
 CommandLineUserInterface::Show()
 {
+       resume_thread(fThread);
 }
 
 
 void
 CommandLineUserInterface::Terminate()
 {
+       fTerminating = true;
+       // TODO: Signal the thread so it wakes up!
+       wait_for_thread(fThread, NULL);
 }
 
 
 status_t
 CommandLineUserInterface::LoadSettings(const TeamUISettings* settings)
 {
-       return B_UNSUPPORTED;
+       return B_OK;
 }
 
 
 status_t
 CommandLineUserInterface::SaveSettings(TeamUISettings*& settings) const
 {
-       return B_UNSUPPORTED;;
+       return B_OK;
 }
 
 
@@ -71,3 +179,125 @@ CommandLineUserInterface::SynchronouslyAskUser(const char* 
title,
 {
        return 0;
 }
+
+
+/*static*/ status_t
+CommandLineUserInterface::_InputLoopEntry(void* data)
+{
+       return ((CommandLineUserInterface*)data)->_InputLoop();
+}
+
+
+status_t
+CommandLineUserInterface::_InputLoop()
+{
+       while (!fTerminating) {
+               // read a command line
+               printf("debugger> ");
+               fflush(stdout);
+               char buffer[256];
+               if (fgets(buffer, sizeof(buffer), stdin) == NULL)
+                       break;
+
+               // parse the command line
+               ArgumentVector args;
+               const char* parseErrorLocation;
+               switch (args.Parse(buffer, &parseErrorLocation)) {
+                       case ArgumentVector::NO_ERROR:
+                               break;
+                       case ArgumentVector::NO_MEMORY:
+                               printf("Insufficient memory parsing the command 
line.\n");
+                               continue;
+                       case ArgumentVector::UNTERMINATED_QUOTED_STRING:
+                               printf("Parse error: Unterminated quoted string 
starting at "
+                                       "character %zu.\n", parseErrorLocation 
- buffer + 1);
+                               continue;
+                       case ArgumentVector::TRAILING_BACKSPACE:
+                               printf("Parse error: trailing backspace.\n");
+                               continue;
+               }
+
+               if (args.ArgumentCount() == 0)
+                       continue;
+
+               _ExecuteCommand(args.ArgumentCount(), args.Arguments());
+       }
+
+       return B_OK;
+}
+
+
+status_t
+CommandLineUserInterface::_RegisterCommands()
+{
+       if (_RegisterCommand("help", new(std::nothrow) HelpCommand(this)) &&
+               _RegisterCommand("quit", new(std::nothrow) QuitCommand(this))) {
+               return B_OK;
+       }
+
+       return B_NO_MEMORY;
+}
+
+
+bool
+CommandLineUserInterface::_RegisterCommand(const BString& name,
+       CliCommand* command)
+{
+       BReference<CliCommand> commandReference(command, true);
+       if (name.IsEmpty() || command == NULL)
+               return false;
+
+       CommandEntry* entry = new(std::nothrow) CommandEntry(name, command);
+       if (entry == NULL || !fCommands.AddItem(entry)) {
+               delete entry;
+               return false;
+       }
+
+       return true;
+}
+
+
+void
+CommandLineUserInterface::_ExecuteCommand(int argc, const char* const* argv)
+{
+       const char* commandName = argv[0];
+       size_t commandNameLength = strlen(commandName);
+
+       CommandEntry* firstEntry = NULL;
+       for (int32 i = 0; CommandEntry* entry = fCommands.ItemAt(i); i++) {
+               if (entry->Name().Compare(commandName, commandNameLength) == 0) 
{
+                       if (firstEntry != NULL) {
+                               printf("Ambiguous command \"%s\".\n", 
commandName);
+                               return;
+                       }
+
+                       firstEntry = entry;
+               }
+       }
+
+       if (firstEntry == NULL) {
+               printf("Unknown command \"%s\".\n", commandName);
+               return;
+       }
+
+       CliContext context;
+       firstEntry->Command()->Execute(argc, argv, context);
+}
+
+
+void
+CommandLineUserInterface::_PrintHelp()
+{
+       // determine longest command name
+       int32 longestCommandName = 0;
+       for (int32 i = 0; CommandEntry* entry = fCommands.ItemAt(i); i++) {
+               longestCommandName
+                       = std::max(longestCommandName, entry->Name().Length());
+       }
+
+       // print the command list
+       for (int32 i = 0; CommandEntry* entry = fCommands.ItemAt(i); i++) {
+               printf("%*s  -  %s\n", (int)longestCommandName, 
entry->Name().String(),
+                       entry->Command()->Summary());
+       }
+}
diff --git a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h 
b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h
index 4d04a7c..b581f36 100644
--- a/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h
+++ b/src/apps/debugger/user_interface/cli/CommandLineUserInterface.h
@@ -1,14 +1,21 @@
 /*
  * Copyright 2011, Rene Gollent, rene@xxxxxxxxxxxx
+ * Copyright 2012, Ingo Weinhold, ingo_weinhold@xxxxxxx
  * Distributed under the terms of the MIT License.
  */
 #ifndef COMMAND_LINE_USER_INTERFACE_H
 #define COMMAND_LINE_USER_INTERFACE_H
 
 
+#include <ObjectList.h>
+#include <String.h>
+
 #include "UserInterface.h"
 
 
+class CliCommand;
+
+
 class CommandLineUserInterface : public UserInterface {
 public:
                                                                
CommandLineUserInterface();
@@ -33,6 +40,34 @@ public:
                                                                        const 
char* message, const char* choice1,
                                                                        const 
char* choice2, const char* choice3);
 
+private:
+                       struct CommandEntry;
+                       typedef BObjectList<CommandEntry> CommandList;
+
+                       struct HelpCommand;
+                       struct QuitCommand;
+
+                       // GCC 2 support
+                       friend struct HelpCommand;
+                       friend struct QuitCommand;
+
+private:
+       static  status_t                        _InputLoopEntry(void* data);
+                       status_t                        _InputLoop();
+
+                       status_t                        _RegisterCommands();
+                       bool                            _RegisterCommand(const 
BString& name,
+                                                                       
CliCommand* command);
+                       void                            _ExecuteCommand(int 
argc,
+                                                                       const 
char* const* argv);
+                       void                            _PrintHelp();
+
+private:
+                       thread_id                       fThread;
+                       Team*                           fTeam;
+                       UserInterfaceListener* fListener;
+                       CommandList                     fCommands;
+                       bool                            fTerminating;
 };
 
 


Other related posts: