From 1b877234dada9f14cebc486cc426db892beae152 Mon Sep 17 00:00:00 2001
From: Melanie Thielker
Date: Mon, 4 May 2009 12:15:55 +0000
Subject: Refactor. Make ConsoleBase a true base class. Create CommandConsole
as a simple console capable of processing commands. Create LocalConsole as a
console that uses cursor control and context help. Precursor to a distributed
console system for the new grid services. No functional change intended :)
---
OpenSim/Framework/Console/CommandConsole.cs | 467 ++++++++++++++++
OpenSim/Framework/Console/ConsoleBase.cs | 829 ++--------------------------
OpenSim/Framework/Console/LocalConsole.cs | 470 ++++++++++++++++
OpenSim/Framework/Console/MainConsole.cs | 4 +-
4 files changed, 970 insertions(+), 800 deletions(-)
create mode 100644 OpenSim/Framework/Console/CommandConsole.cs
create mode 100644 OpenSim/Framework/Console/LocalConsole.cs
(limited to 'OpenSim/Framework/Console')
diff --git a/OpenSim/Framework/Console/CommandConsole.cs b/OpenSim/Framework/Console/CommandConsole.cs
new file mode 100644
index 0000000..0c314b9
--- /dev/null
+++ b/OpenSim/Framework/Console/CommandConsole.cs
@@ -0,0 +1,467 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using log4net;
+
+namespace OpenSim.Framework.Console
+{
+ public delegate void CommandDelegate(string module, string[] cmd);
+
+ public class Commands
+ {
+ ///
+ /// Encapsulates a command that can be invoked from the console
+ ///
+ private class CommandInfo
+ {
+ ///
+ /// The module from which this command comes
+ ///
+ public string module;
+
+ ///
+ /// Whether the module is shared
+ ///
+ public bool shared;
+
+ ///
+ /// Very short BNF description
+ ///
+ public string help_text;
+
+ ///
+ /// Longer one line help text
+ ///
+ public string long_help;
+
+ ///
+ /// Full descriptive help for this command
+ ///
+ public string descriptive_help;
+
+ ///
+ /// The method to invoke for this command
+ ///
+ public List fn;
+ }
+
+ ///
+ /// Commands organized by keyword in a tree
+ ///
+ private Dictionary tree =
+ new Dictionary();
+
+ ///
+ /// Get help for the given help string
+ ///
+ /// Parsed parts of the help string. If empty then general help is returned.
+ ///
+ public List GetHelp(string[] cmd)
+ {
+ List help = new List();
+ List helpParts = new List(cmd);
+
+ // Remove initial help keyword
+ helpParts.RemoveAt(0);
+
+ // General help
+ if (helpParts.Count == 0)
+ {
+ help.AddRange(CollectHelp(tree));
+ help.Sort();
+ }
+ else
+ {
+ help.AddRange(CollectHelp(helpParts));
+ }
+
+ return help;
+ }
+
+ ///
+ /// See if we can find the requested command in order to display longer help
+ ///
+ ///
+ ///
+ private List CollectHelp(List helpParts)
+ {
+ string originalHelpRequest = string.Join(" ", helpParts.ToArray());
+ List help = new List();
+
+ Dictionary dict = tree;
+ while (helpParts.Count > 0)
+ {
+ string helpPart = helpParts[0];
+
+ if (!dict.ContainsKey(helpPart))
+ break;
+
+ //m_log.Debug("Found {0}", helpParts[0]);
+
+ if (dict[helpPart] is Dictionary)
+ dict = (Dictionary)dict[helpPart];
+
+ helpParts.RemoveAt(0);
+ }
+
+ // There was a command for the given help string
+ if (dict.ContainsKey(String.Empty))
+ {
+ CommandInfo commandInfo = (CommandInfo)dict[String.Empty];
+ help.Add(commandInfo.help_text);
+ help.Add(commandInfo.long_help);
+ help.Add(commandInfo.descriptive_help);
+ }
+ else
+ {
+ help.Add(string.Format("No help is available for {0}", originalHelpRequest));
+ }
+
+ return help;
+ }
+
+ private List CollectHelp(Dictionary dict)
+ {
+ List result = new List();
+
+ foreach (KeyValuePair kvp in dict)
+ {
+ if (kvp.Value is Dictionary)
+ {
+ result.AddRange(CollectHelp((Dictionary)kvp.Value));
+ }
+ else
+ {
+ if (((CommandInfo)kvp.Value).long_help != String.Empty)
+ result.Add(((CommandInfo)kvp.Value).help_text+" - "+
+ ((CommandInfo)kvp.Value).long_help);
+ }
+ }
+ return result;
+ }
+
+ ///
+ /// Add a command to those which can be invoked from the console.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void AddCommand(string module, bool shared, string command,
+ string help, string longhelp, CommandDelegate fn)
+ {
+ AddCommand(module, shared, command, help, longhelp,
+ String.Empty, fn);
+ }
+
+ ///
+ /// Add a command to those which can be invoked from the console.
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ ///
+ public void AddCommand(string module, bool shared, string command,
+ string help, string longhelp, string descriptivehelp,
+ CommandDelegate fn)
+ {
+ string[] parts = Parser.Parse(command);
+
+ Dictionary current = tree;
+
+ foreach (string s in parts)
+ {
+ if (current.ContainsKey(s))
+ {
+ if (current[s] is Dictionary)
+ {
+ current = (Dictionary)current[s];
+ }
+ else
+ return;
+ }
+ else
+ {
+ current[s] = new Dictionary();
+ current = (Dictionary)current[s];
+ }
+ }
+
+ CommandInfo info;
+
+ if (current.ContainsKey(String.Empty))
+ {
+ info = (CommandInfo)current[String.Empty];
+ if (!info.shared && !info.fn.Contains(fn))
+ info.fn.Add(fn);
+
+ return;
+ }
+
+ info = new CommandInfo();
+ info.module = module;
+ info.shared = shared;
+ info.help_text = help;
+ info.long_help = longhelp;
+ info.descriptive_help = descriptivehelp;
+ info.fn = new List();
+ info.fn.Add(fn);
+ current[String.Empty] = info;
+ }
+
+ public string[] FindNextOption(string[] cmd, bool term)
+ {
+ Dictionary current = tree;
+
+ int remaining = cmd.Length;
+
+ foreach (string s in cmd)
+ {
+ remaining--;
+
+ List found = new List();
+
+ foreach (string opt in current.Keys)
+ {
+ if (remaining > 0 && opt == s)
+ {
+ found.Clear();
+ found.Add(opt);
+ break;
+ }
+ if (opt.StartsWith(s))
+ {
+ found.Add(opt);
+ }
+ }
+
+ if (found.Count == 1 && (remaining != 0 || term))
+ {
+ current = (Dictionary)current[found[0]];
+ }
+ else if (found.Count > 0)
+ {
+ return found.ToArray();
+ }
+ else
+ {
+ break;
+// return new string[] {""};
+ }
+ }
+
+ if (current.Count > 1)
+ {
+ List choices = new List();
+
+ bool addcr = false;
+ foreach (string s in current.Keys)
+ {
+ if (s == String.Empty)
+ {
+ CommandInfo ci = (CommandInfo)current[String.Empty];
+ if (ci.fn.Count != 0)
+ addcr = true;
+ }
+ else
+ choices.Add(s);
+ }
+ if (addcr)
+ choices.Add("");
+ return choices.ToArray();
+ }
+
+ if (current.ContainsKey(String.Empty))
+ return new string[] { "Command help: "+((CommandInfo)current[String.Empty]).help_text};
+
+ return new string[] { new List(current.Keys)[0] };
+ }
+
+ public string[] Resolve(string[] cmd)
+ {
+ string[] result = cmd;
+ int index = -1;
+
+ Dictionary current = tree;
+
+ foreach (string s in cmd)
+ {
+ index++;
+
+ List found = new List();
+
+ foreach (string opt in current.Keys)
+ {
+ if (opt == s)
+ {
+ found.Clear();
+ found.Add(opt);
+ break;
+ }
+ if (opt.StartsWith(s))
+ {
+ found.Add(opt);
+ }
+ }
+
+ if (found.Count == 1)
+ {
+ result[index] = found[0];
+ current = (Dictionary)current[found[0]];
+ }
+ else if (found.Count > 0)
+ {
+ return new string[0];
+ }
+ else
+ {
+ break;
+ }
+ }
+
+ if (current.ContainsKey(String.Empty))
+ {
+ CommandInfo ci = (CommandInfo)current[String.Empty];
+ if (ci.fn.Count == 0)
+ return new string[0];
+ foreach (CommandDelegate fn in ci.fn)
+ {
+ if (fn != null)
+ fn(ci.module, result);
+ else
+ return new string[0];
+ }
+ return result;
+ }
+
+ return new string[0];
+ }
+ }
+
+ public class Parser
+ {
+ public static string[] Parse(string text)
+ {
+ List result = new List();
+
+ int index;
+
+ string[] unquoted = text.Split(new char[] {'"'});
+
+ for (index = 0 ; index < unquoted.Length ; index++)
+ {
+ if (index % 2 == 0)
+ {
+ string[] words = unquoted[index].Split(new char[] {' '});
+ foreach (string w in words)
+ {
+ if (w != String.Empty)
+ result.Add(w);
+ }
+ }
+ else
+ {
+ result.Add(unquoted[index]);
+ }
+ }
+
+ return result.ToArray();
+ }
+ }
+
+ // A console that processes commands internally
+ //
+ public class CommandConsole : ConsoleBase
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ public Commands Commands = new Commands();
+
+ public CommandConsole(string defaultPrompt) : base(defaultPrompt)
+ {
+ Commands.AddCommand("console", false, "help", "help []",
+ "Get general command list or more detailed help on a specific command", Help);
+ }
+
+ private void Help(string module, string[] cmd)
+ {
+ List help = Commands.GetHelp(cmd);
+
+ foreach (string s in help)
+ Output(s);
+ }
+
+ public void Prompt()
+ {
+ string line = ReadLine(m_defaultPrompt, true, true);
+
+ if (line != String.Empty)
+ {
+ m_log.Info("Invalid command");
+ }
+ }
+
+ public void RunCommand(string cmd)
+ {
+ string[] parts = Parser.Parse(cmd);
+ Commands.Resolve(parts);
+ }
+
+ public override string ReadLine(string p, bool isCommand, bool e)
+ {
+ System.Console.Write("{0}", prompt);
+ string cmdinput = System.Console.ReadLine();
+
+ if (isCommand)
+ {
+ string[] cmd = Commands.Resolve(Parser.Parse(cmdinput));
+
+ if (cmd.Length != 0)
+ {
+ int i;
+
+ for (i=0 ; i < cmd.Length ; i++)
+ {
+ if (cmd[i].Contains(" "))
+ cmd[i] = "\"" + cmd[i] + "\"";
+ }
+ return String.Empty;
+ }
+ }
+ return cmdinput;
+ }
+ }
+}
diff --git a/OpenSim/Framework/Console/ConsoleBase.cs b/OpenSim/Framework/Console/ConsoleBase.cs
index fda2037..30493fc 100644
--- a/OpenSim/Framework/Console/ConsoleBase.cs
+++ b/OpenSim/Framework/Console/ConsoleBase.cs
@@ -35,388 +35,11 @@ using log4net;
namespace OpenSim.Framework.Console
{
- public delegate void CommandDelegate(string module, string[] cmd);
-
- public class Commands
- {
- ///
- /// Encapsulates a command that can be invoked from the console
- ///
- private class CommandInfo
- {
- ///
- /// The module from which this command comes
- ///
- public string module;
-
- ///
- /// Whether the module is shared
- ///
- public bool shared;
-
- ///
- /// Very short BNF description
- ///
- public string help_text;
-
- ///
- /// Longer one line help text
- ///
- public string long_help;
-
- ///
- /// Full descriptive help for this command
- ///
- public string descriptive_help;
-
- ///
- /// The method to invoke for this command
- ///
- public List fn;
- }
-
- ///
- /// Commands organized by keyword in a tree
- ///
- private Dictionary tree =
- new Dictionary();
-
- ///
- /// Get help for the given help string
- ///
- /// Parsed parts of the help string. If empty then general help is returned.
- ///
- public List GetHelp(string[] cmd)
- {
- List help = new List();
- List helpParts = new List(cmd);
-
- // Remove initial help keyword
- helpParts.RemoveAt(0);
-
- // General help
- if (helpParts.Count == 0)
- {
- help.AddRange(CollectHelp(tree));
- help.Sort();
- }
- else
- {
- help.AddRange(CollectHelp(helpParts));
- }
-
- return help;
- }
-
- ///
- /// See if we can find the requested command in order to display longer help
- ///
- ///
- ///
- private List CollectHelp(List helpParts)
- {
- string originalHelpRequest = string.Join(" ", helpParts.ToArray());
- List help = new List();
-
- Dictionary dict = tree;
- while (helpParts.Count > 0)
- {
- string helpPart = helpParts[0];
-
- if (!dict.ContainsKey(helpPart))
- break;
-
- //m_log.Debug("Found {0}", helpParts[0]);
-
- if (dict[helpPart] is Dictionary)
- dict = (Dictionary)dict[helpPart];
-
- helpParts.RemoveAt(0);
- }
-
- // There was a command for the given help string
- if (dict.ContainsKey(String.Empty))
- {
- CommandInfo commandInfo = (CommandInfo)dict[String.Empty];
- help.Add(commandInfo.help_text);
- help.Add(commandInfo.long_help);
- help.Add(commandInfo.descriptive_help);
- }
- else
- {
- help.Add(string.Format("No help is available for {0}", originalHelpRequest));
- }
-
- return help;
- }
-
- private List CollectHelp(Dictionary dict)
- {
- List result = new List();
-
- foreach (KeyValuePair kvp in dict)
- {
- if (kvp.Value is Dictionary)
- {
- result.AddRange(CollectHelp((Dictionary)kvp.Value));
- }
- else
- {
- if (((CommandInfo)kvp.Value).long_help != String.Empty)
- result.Add(((CommandInfo)kvp.Value).help_text+" - "+
- ((CommandInfo)kvp.Value).long_help);
- }
- }
- return result;
- }
-
- ///
- /// Add a command to those which can be invoked from the console.
- ///
- ///
- ///
- ///
- ///
- ///
- public void AddCommand(string module, bool shared, string command,
- string help, string longhelp, CommandDelegate fn)
- {
- AddCommand(module, shared, command, help, longhelp,
- String.Empty, fn);
- }
-
- ///
- /// Add a command to those which can be invoked from the console.
- ///
- ///
- ///
- ///
- ///
- ///
- ///
- public void AddCommand(string module, bool shared, string command,
- string help, string longhelp, string descriptivehelp,
- CommandDelegate fn)
- {
- string[] parts = Parser.Parse(command);
-
- Dictionary current = tree;
-
- foreach (string s in parts)
- {
- if (current.ContainsKey(s))
- {
- if (current[s] is Dictionary)
- {
- current = (Dictionary)current[s];
- }
- else
- return;
- }
- else
- {
- current[s] = new Dictionary();
- current = (Dictionary)current[s];
- }
- }
-
- CommandInfo info;
-
- if (current.ContainsKey(String.Empty))
- {
- info = (CommandInfo)current[String.Empty];
- if (!info.shared && !info.fn.Contains(fn))
- info.fn.Add(fn);
-
- return;
- }
-
- info = new CommandInfo();
- info.module = module;
- info.shared = shared;
- info.help_text = help;
- info.long_help = longhelp;
- info.descriptive_help = descriptivehelp;
- info.fn = new List();
- info.fn.Add(fn);
- current[String.Empty] = info;
- }
-
- public string[] FindNextOption(string[] cmd, bool term)
- {
- Dictionary current = tree;
-
- int remaining = cmd.Length;
-
- foreach (string s in cmd)
- {
- remaining--;
-
- List found = new List();
-
- foreach (string opt in current.Keys)
- {
- if (remaining > 0 && opt == s)
- {
- found.Clear();
- found.Add(opt);
- break;
- }
- if (opt.StartsWith(s))
- {
- found.Add(opt);
- }
- }
-
- if (found.Count == 1 && (remaining != 0 || term))
- {
- current = (Dictionary)current[found[0]];
- }
- else if (found.Count > 0)
- {
- return found.ToArray();
- }
- else
- {
- break;
-// return new string[] {""};
- }
- }
-
- if (current.Count > 1)
- {
- List choices = new List();
-
- bool addcr = false;
- foreach (string s in current.Keys)
- {
- if (s == String.Empty)
- {
- CommandInfo ci = (CommandInfo)current[String.Empty];
- if (ci.fn.Count != 0)
- addcr = true;
- }
- else
- choices.Add(s);
- }
- if (addcr)
- choices.Add("");
- return choices.ToArray();
- }
-
- if (current.ContainsKey(String.Empty))
- return new string[] { "Command help: "+((CommandInfo)current[String.Empty]).help_text};
-
- return new string[] { new List(current.Keys)[0] };
- }
-
- public string[] Resolve(string[] cmd)
- {
- string[] result = cmd;
- int index = -1;
-
- Dictionary current = tree;
-
- foreach (string s in cmd)
- {
- index++;
-
- List found = new List();
-
- foreach (string opt in current.Keys)
- {
- if (opt == s)
- {
- found.Clear();
- found.Add(opt);
- break;
- }
- if (opt.StartsWith(s))
- {
- found.Add(opt);
- }
- }
-
- if (found.Count == 1)
- {
- result[index] = found[0];
- current = (Dictionary)current[found[0]];
- }
- else if (found.Count > 0)
- {
- return new string[0];
- }
- else
- {
- break;
- }
- }
-
- if (current.ContainsKey(String.Empty))
- {
- CommandInfo ci = (CommandInfo)current[String.Empty];
- if (ci.fn.Count == 0)
- return new string[0];
- foreach (CommandDelegate fn in ci.fn)
- {
- if (fn != null)
- fn(ci.module, result);
- else
- return new string[0];
- }
- return result;
- }
-
- return new string[0];
- }
- }
-
- public class Parser
- {
- public static string[] Parse(string text)
- {
- List result = new List();
-
- int index;
-
- string[] unquoted = text.Split(new char[] {'"'});
-
- for (index = 0 ; index < unquoted.Length ; index++)
- {
- if (index % 2 == 0)
- {
- string[] words = unquoted[index].Split(new char[] {' '});
- foreach (string w in words)
- {
- if (w != String.Empty)
- result.Add(w);
- }
- }
- else
- {
- result.Add(unquoted[index]);
- }
- }
-
- return result.ToArray();
- }
- }
-
public class ConsoleBase
{
private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
- private readonly object m_syncRoot = new object();
-
- private int y = -1;
- private int cp = 0;
- private int h = 1;
- private string prompt = "# ";
- private StringBuilder cmdline = new StringBuilder();
- public Commands Commands = new Commands();
- private bool echo = true;
- private List history = new List();
- private bool gui = false;
+ protected string prompt = "# ";
public object ConsoleScene = null;
@@ -433,22 +56,6 @@ namespace OpenSim.Framework.Console
public ConsoleBase(string defaultPrompt)
{
DefaultPrompt = defaultPrompt;
-
- Commands.AddCommand("console", false, "help", "help []",
- "Get general command list or more detailed help on a specific command", Help);
- }
-
- public void SetGuiMode(bool mode)
- {
- gui = mode;
- }
-
- private void AddToHistory(string text)
- {
- while (history.Count >= 100)
- history.RemoveAt(0);
-
- history.Add(text);
}
///
@@ -458,10 +65,9 @@ namespace OpenSim.Framework.Console
///
/// arbitrary string for input
/// an ansii color
- private static ConsoleColor DeriveColor(string input)
+ protected virtual ConsoleColor DeriveColor(string input)
{
- int colIdx = (input.ToUpper().GetHashCode() % 6) + 9;
- return (ConsoleColor) colIdx;
+ return ConsoleColor.White;
}
///
@@ -559,280 +165,58 @@ namespace OpenSim.Framework.Console
WriteNewLine(DeriveColor(sender), sender, ConsoleColor.Gray, format, args);
}
- private int SetCursorTop(int top)
+ protected virtual void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
{
- if (top >= 0 && top < System.Console.BufferHeight)
- {
- System.Console.CursorTop = top;
- return top;
- }
- else
- {
- return System.Console.CursorTop;
- }
+ WritePrefixLine(senderColor, sender);
+ WriteConsoleLine(color, format, args);
}
- private int SetCursorLeft(int left)
+ protected virtual void WriteNewLine(ConsoleColor color, string format, params object[] args)
{
- if (left >= 0 && left < System.Console.BufferWidth)
- {
- System.Console.CursorLeft = left;
- return left;
- }
- else
- {
- return System.Console.CursorLeft;
- }
+ WriteConsoleLine(color, format, args);
}
- private void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
- {
- lock (cmdline)
- {
- if (y != -1)
- {
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
-
- int count = cmdline.Length;
-
- System.Console.Write(" ");
- while (count-- > 0)
- System.Console.Write(" ");
-
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
- }
- WritePrefixLine(senderColor, sender);
- WriteConsoleLine(color, format, args);
- if (y != -1)
- y = System.Console.CursorTop;
- }
- }
-
- private void WriteNewLine(ConsoleColor color, string format, params object[] args)
- {
- lock (cmdline)
- {
- if (y != -1)
- {
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
-
- int count = cmdline.Length;
-
- System.Console.Write(" ");
- while (count-- > 0)
- System.Console.Write(" ");
-
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
- }
- WriteConsoleLine(color, format, args);
- if (y != -1)
- y = System.Console.CursorTop;
- }
- }
-
- private void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
+ protected virtual void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
{
try
{
- lock (m_syncRoot)
- {
- try
- {
- if (color != ConsoleColor.White)
- System.Console.ForegroundColor = color;
-
- System.Console.WriteLine(format, args);
- System.Console.ResetColor();
- }
- catch (ArgumentNullException)
- {
- // Some older systems dont support coloured text.
- System.Console.WriteLine(format, args);
- }
- catch (FormatException)
- {
- System.Console.WriteLine(args);
- }
- }
+ System.Console.WriteLine(format, args);
}
catch (ObjectDisposedException)
{
}
}
- private void WritePrefixLine(ConsoleColor color, string sender)
+ protected virtual void WritePrefixLine(ConsoleColor color, string sender)
{
try
{
- lock (m_syncRoot)
- {
- sender = sender.ToUpper();
+ sender = sender.ToUpper();
- System.Console.WriteLine("[" + sender + "] ");
+ System.Console.WriteLine("[" + sender + "] ");
- System.Console.Write("[");
+ System.Console.Write("[");
- try
- {
- System.Console.ForegroundColor = color;
- System.Console.Write(sender);
- System.Console.ResetColor();
- }
- catch (ArgumentNullException)
- {
- // Some older systems dont support coloured text.
- System.Console.WriteLine(sender);
- }
+ System.Console.Write(sender);
- System.Console.Write("] \t");
- }
+ System.Console.Write("] \t");
}
catch (ObjectDisposedException)
{
}
}
- private void Help(string module, string[] cmd)
- {
- List help = Commands.GetHelp(cmd);
-
- foreach (string s in help)
- Output(s);
- }
-
- private void Show()
- {
- lock (cmdline)
- {
- if (y == -1 || System.Console.BufferWidth == 0)
- return;
-
- int xc = prompt.Length + cp;
- int new_x = xc % System.Console.BufferWidth;
- int new_y = y + xc / System.Console.BufferWidth;
- int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
- if (end_y / System.Console.BufferWidth >= h)
- h++;
- if (end_y >= System.Console.BufferHeight) // wrap
- {
- y--;
- new_y--;
- System.Console.CursorLeft = 0;
- System.Console.CursorTop = System.Console.BufferHeight-1;
- System.Console.WriteLine(" ");
- }
-
- y=SetCursorTop(y);
- System.Console.CursorLeft = 0;
-
- if (echo)
- System.Console.Write("{0}{1}", prompt, cmdline);
- else
- System.Console.Write("{0}", prompt);
-
- SetCursorLeft(new_x);
- SetCursorTop(new_y);
- }
- }
-
- public void LockOutput()
- {
- Monitor.Enter(cmdline);
- try
- {
- if (y != -1)
- {
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
-
- int count = cmdline.Length + prompt.Length;
-
- while (count-- > 0)
- System.Console.Write(" ");
-
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
-
- }
- }
- catch (Exception)
- {
- }
- }
-
- public void UnlockOutput()
+ public virtual void LockOutput()
{
- if (y != -1)
- {
- y = System.Console.CursorTop;
- Show();
- }
- Monitor.Exit(cmdline);
}
- public void Output(string text)
+ public virtual void UnlockOutput()
{
- lock (cmdline)
- {
- if (y == -1)
- {
- System.Console.WriteLine(text);
-
- return;
- }
-
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
-
- int count = cmdline.Length + prompt.Length;
-
- while (count-- > 0)
- System.Console.Write(" ");
-
- y = SetCursorTop(y);
- System.Console.CursorLeft = 0;
-
- System.Console.WriteLine(text);
-
- y = System.Console.CursorTop;
-
- Show();
- }
- }
-
- private bool ContextHelp()
- {
- string[] words = Parser.Parse(cmdline.ToString());
-
- bool trailingSpace = cmdline.ToString().EndsWith(" ");
-
- // Allow ? through while typing a URI
- //
- if (words.Length > 0 && words[words.Length-1].StartsWith("http") && !trailingSpace)
- return false;
-
- string[] opts = Commands.FindNextOption(words, trailingSpace);
-
- if (opts[0].StartsWith("Command help:"))
- Output(opts[0]);
- else
- Output(String.Format("Options: {0}", String.Join(" ", opts)));
-
- return true;
}
- public void Prompt()
+ public virtual void Output(string text)
{
- string line = ReadLine(m_defaultPrompt, true, true);
-
- if (line != String.Empty)
- {
- m_log.Info("Invalid command");
- }
+ System.Console.WriteLine(text);
}
public string CmdPrompt(string p)
@@ -850,19 +234,23 @@ namespace OpenSim.Framework.Console
}
// Displays a command prompt and returns a default value, user may only enter 1 of 2 options
- public string CmdPrompt(string prompt, string defaultresponse, string OptionA, string OptionB)
+ public string CmdPrompt(string prompt, string defaultresponse, List options)
{
bool itisdone = false;
+ string optstr = String.Empty;
+ foreach (string s in options)
+ optstr += " " + s;
+
string temp = CmdPrompt(prompt, defaultresponse);
while (itisdone == false)
{
- if ((temp == OptionA) || (temp == OptionB))
+ if (options.Contains(temp))
{
itisdone = true;
}
else
{
- System.Console.WriteLine("Valid options are " + OptionA + " or " + OptionB);
+ System.Console.WriteLine("Valid options are" + optstr);
temp = CmdPrompt(prompt, defaultresponse);
}
}
@@ -876,167 +264,12 @@ namespace OpenSim.Framework.Console
return ReadLine(p, false, false);
}
- public void RunCommand(string cmd)
- {
- string[] parts = Parser.Parse(cmd);
- Commands.Resolve(parts);
- }
-
- public string ReadLine(string p, bool isCommand, bool e)
+ public virtual string ReadLine(string p, bool isCommand, bool e)
{
- h = 1;
- cp = 0;
- prompt = p;
- echo = e;
- int historyLine = history.Count;
+ System.Console.Write("{0}", prompt);
+ string cmdinput = System.Console.ReadLine();
- if (gui)
- {
- System.Console.Write("{0}", prompt);
- string cmdinput = System.Console.ReadLine();
-
- if (isCommand)
- {
- string[] cmd = Commands.Resolve(Parser.Parse(cmdinput));
-
- if (cmd.Length != 0)
- {
- int i;
-
- for (i=0 ; i < cmd.Length ; i++)
- {
- if (cmd[i].Contains(" "))
- cmd[i] = "\"" + cmd[i] + "\"";
- }
- return String.Empty;
- }
- }
- return cmdinput;
- }
-
- System.Console.CursorLeft = 0; // Needed for mono
- System.Console.Write(" "); // Needed for mono
-
- lock (cmdline)
- {
- y = System.Console.CursorTop;
- cmdline.Remove(0, cmdline.Length);
- }
-
- while (true)
- {
- Show();
-
- ConsoleKeyInfo key = System.Console.ReadKey(true);
- char c = key.KeyChar;
-
- if (!Char.IsControl(c))
- {
- if (cp >= 318)
- continue;
-
- if (c == '?' && isCommand)
- {
- if (ContextHelp())
- continue;
- }
-
- cmdline.Insert(cp, c);
- cp++;
- }
- else
- {
- switch (key.Key)
- {
- case ConsoleKey.Backspace:
- if (cp == 0)
- break;
- cmdline.Remove(cp-1, 1);
- cp--;
-
- System.Console.CursorLeft = 0;
- y = SetCursorTop(y);
-
- System.Console.Write("{0}{1} ", prompt, cmdline);
-
- break;
- case ConsoleKey.End:
- cp = cmdline.Length;
- break;
- case ConsoleKey.Home:
- cp = 0;
- break;
- case ConsoleKey.UpArrow:
- if (historyLine < 1)
- break;
- historyLine--;
- LockOutput();
- cmdline.Remove(0, cmdline.Length);
- cmdline.Append(history[historyLine]);
- cp = cmdline.Length;
- UnlockOutput();
- break;
- case ConsoleKey.DownArrow:
- if (historyLine >= history.Count)
- break;
- historyLine++;
- LockOutput();
- if (historyLine == history.Count)
- {
- cmdline.Remove(0, cmdline.Length);
- }
- else
- {
- cmdline.Remove(0, cmdline.Length);
- cmdline.Append(history[historyLine]);
- }
- cp = cmdline.Length;
- UnlockOutput();
- break;
- case ConsoleKey.LeftArrow:
- if (cp > 0)
- cp--;
- break;
- case ConsoleKey.RightArrow:
- if (cp < cmdline.Length)
- cp++;
- break;
- case ConsoleKey.Enter:
- System.Console.CursorLeft = 0;
- y = SetCursorTop(y);
-
- System.Console.WriteLine("{0}{1}", prompt, cmdline);
-
- lock (cmdline)
- {
- y = -1;
- }
-
- if (isCommand)
- {
- string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
-
- if (cmd.Length != 0)
- {
- int i;
-
- for (i=0 ; i < cmd.Length ; i++)
- {
- if (cmd[i].Contains(" "))
- cmd[i] = "\"" + cmd[i] + "\"";
- }
- AddToHistory(String.Join(" ", cmd));
- return String.Empty;
- }
- }
-
- AddToHistory(cmdline.ToString());
- return cmdline.ToString();
- default:
- break;
- }
- }
- }
+ return cmdinput;
}
}
}
diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs
new file mode 100644
index 0000000..9dde969
--- /dev/null
+++ b/OpenSim/Framework/Console/LocalConsole.cs
@@ -0,0 +1,470 @@
+/*
+ * Copyright (c) Contributors, http://opensimulator.org/
+ * See CONTRIBUTORS.TXT for a full list of copyright holders.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * * Neither the name of the OpenSim Project nor the
+ * names of its contributors may be used to endorse or promote products
+ * derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+ * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
+ * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
+ * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
+ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Text;
+using System.Threading;
+using log4net;
+
+namespace OpenSim.Framework.Console
+{
+ // A console that uses cursor control and color
+ //
+ public class LocalConsole : CommandConsole
+ {
+ private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
+
+ private readonly object m_syncRoot = new object();
+
+ private int y = -1;
+ private int cp = 0;
+ private int h = 1;
+ private string prompt = "# ";
+ private StringBuilder cmdline = new StringBuilder();
+ private bool echo = true;
+ private List history = new List();
+
+ public LocalConsole(string defaultPrompt) : base(defaultPrompt)
+ {
+ }
+
+ private void AddToHistory(string text)
+ {
+ while (history.Count >= 100)
+ history.RemoveAt(0);
+
+ history.Add(text);
+ }
+
+ ///
+ /// derive an ansi color from a string, ignoring the darker colors.
+ /// This is used to help automatically bin component tags with colors
+ /// in various print functions.
+ ///
+ /// arbitrary string for input
+ /// an ansii color
+ protected override ConsoleColor DeriveColor(string input)
+ {
+ int colIdx = (input.ToUpper().GetHashCode() % 6) + 9;
+ return (ConsoleColor) colIdx;
+ }
+
+ private int SetCursorTop(int top)
+ {
+ if (top >= 0 && top < System.Console.BufferHeight)
+ {
+ System.Console.CursorTop = top;
+ return top;
+ }
+ else
+ {
+ return System.Console.CursorTop;
+ }
+ }
+
+ private int SetCursorLeft(int left)
+ {
+ if (left >= 0 && left < System.Console.BufferWidth)
+ {
+ System.Console.CursorLeft = left;
+ return left;
+ }
+ else
+ {
+ return System.Console.CursorLeft;
+ }
+ }
+
+ protected override void WriteNewLine(ConsoleColor senderColor, string sender, ConsoleColor color, string format, params object[] args)
+ {
+ lock (cmdline)
+ {
+ if (y != -1)
+ {
+ y=SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+
+ int count = cmdline.Length;
+
+ System.Console.Write(" ");
+ while (count-- > 0)
+ System.Console.Write(" ");
+
+ y=SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+ }
+ WritePrefixLine(senderColor, sender);
+ WriteConsoleLine(color, format, args);
+ if (y != -1)
+ y = System.Console.CursorTop;
+ }
+ }
+
+ protected override void WriteNewLine(ConsoleColor color, string format, params object[] args)
+ {
+ lock (cmdline)
+ {
+ if (y != -1)
+ {
+ y=SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+
+ int count = cmdline.Length;
+
+ System.Console.Write(" ");
+ while (count-- > 0)
+ System.Console.Write(" ");
+
+ y=SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+ }
+ WriteConsoleLine(color, format, args);
+ if (y != -1)
+ y = System.Console.CursorTop;
+ }
+ }
+
+ protected override void WriteConsoleLine(ConsoleColor color, string format, params object[] args)
+ {
+ try
+ {
+ lock (m_syncRoot)
+ {
+ try
+ {
+ if (color != ConsoleColor.White)
+ System.Console.ForegroundColor = color;
+
+ System.Console.WriteLine(format, args);
+ System.Console.ResetColor();
+ }
+ catch (ArgumentNullException)
+ {
+ // Some older systems dont support coloured text.
+ System.Console.WriteLine(format, args);
+ }
+ catch (FormatException)
+ {
+ System.Console.WriteLine(args);
+ }
+ }
+ }
+ catch (ObjectDisposedException)
+ {
+ }
+ }
+
+ protected override void WritePrefixLine(ConsoleColor color, string sender)
+ {
+ try
+ {
+ lock (m_syncRoot)
+ {
+ sender = sender.ToUpper();
+
+ System.Console.WriteLine("[" + sender + "] ");
+
+ System.Console.Write("[");
+
+ try
+ {
+ System.Console.ForegroundColor = color;
+ System.Console.Write(sender);
+ System.Console.ResetColor();
+ }
+ catch (ArgumentNullException)
+ {
+ // Some older systems dont support coloured text.
+ System.Console.WriteLine(sender);
+ }
+
+ System.Console.Write("] \t");
+ }
+ }
+ catch (ObjectDisposedException)
+ {
+ }
+ }
+
+ private void Show()
+ {
+ lock (cmdline)
+ {
+ if (y == -1 || System.Console.BufferWidth == 0)
+ return;
+
+ int xc = prompt.Length + cp;
+ int new_x = xc % System.Console.BufferWidth;
+ int new_y = y + xc / System.Console.BufferWidth;
+ int end_y = y + (cmdline.Length + prompt.Length) / System.Console.BufferWidth;
+ if (end_y / System.Console.BufferWidth >= h)
+ h++;
+ if (end_y >= System.Console.BufferHeight) // wrap
+ {
+ y--;
+ new_y--;
+ System.Console.CursorLeft = 0;
+ System.Console.CursorTop = System.Console.BufferHeight-1;
+ System.Console.WriteLine(" ");
+ }
+
+ y=SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+
+ if (echo)
+ System.Console.Write("{0}{1}", prompt, cmdline);
+ else
+ System.Console.Write("{0}", prompt);
+
+ SetCursorLeft(new_x);
+ SetCursorTop(new_y);
+ }
+ }
+
+ public override void LockOutput()
+ {
+ Monitor.Enter(cmdline);
+ try
+ {
+ if (y != -1)
+ {
+ y = SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+
+ int count = cmdline.Length + prompt.Length;
+
+ while (count-- > 0)
+ System.Console.Write(" ");
+
+ y = SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+
+ }
+ }
+ catch (Exception)
+ {
+ }
+ }
+
+ public override void UnlockOutput()
+ {
+ if (y != -1)
+ {
+ y = System.Console.CursorTop;
+ Show();
+ }
+ Monitor.Exit(cmdline);
+ }
+
+ public override void Output(string text)
+ {
+ lock (cmdline)
+ {
+ if (y == -1)
+ {
+ System.Console.WriteLine(text);
+
+ return;
+ }
+
+ y = SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+
+ int count = cmdline.Length + prompt.Length;
+
+ while (count-- > 0)
+ System.Console.Write(" ");
+
+ y = SetCursorTop(y);
+ System.Console.CursorLeft = 0;
+
+ System.Console.WriteLine(text);
+
+ y = System.Console.CursorTop;
+
+ Show();
+ }
+ }
+
+ private bool ContextHelp()
+ {
+ string[] words = Parser.Parse(cmdline.ToString());
+
+ bool trailingSpace = cmdline.ToString().EndsWith(" ");
+
+ // Allow ? through while typing a URI
+ //
+ if (words.Length > 0 && words[words.Length-1].StartsWith("http") && !trailingSpace)
+ return false;
+
+ string[] opts = Commands.FindNextOption(words, trailingSpace);
+
+ if (opts[0].StartsWith("Command help:"))
+ Output(opts[0]);
+ else
+ Output(String.Format("Options: {0}", String.Join(" ", opts)));
+
+ return true;
+ }
+
+ public override string ReadLine(string p, bool isCommand, bool e)
+ {
+ h = 1;
+ cp = 0;
+ prompt = p;
+ echo = e;
+ int historyLine = history.Count;
+
+ System.Console.CursorLeft = 0; // Needed for mono
+ System.Console.Write(" "); // Needed for mono
+
+ lock (cmdline)
+ {
+ y = System.Console.CursorTop;
+ cmdline.Remove(0, cmdline.Length);
+ }
+
+ while (true)
+ {
+ Show();
+
+ ConsoleKeyInfo key = System.Console.ReadKey(true);
+ char c = key.KeyChar;
+
+ if (!Char.IsControl(c))
+ {
+ if (cp >= 318)
+ continue;
+
+ if (c == '?' && isCommand)
+ {
+ if (ContextHelp())
+ continue;
+ }
+
+ cmdline.Insert(cp, c);
+ cp++;
+ }
+ else
+ {
+ switch (key.Key)
+ {
+ case ConsoleKey.Backspace:
+ if (cp == 0)
+ break;
+ cmdline.Remove(cp-1, 1);
+ cp--;
+
+ System.Console.CursorLeft = 0;
+ y = SetCursorTop(y);
+
+ System.Console.Write("{0}{1} ", prompt, cmdline);
+
+ break;
+ case ConsoleKey.End:
+ cp = cmdline.Length;
+ break;
+ case ConsoleKey.Home:
+ cp = 0;
+ break;
+ case ConsoleKey.UpArrow:
+ if (historyLine < 1)
+ break;
+ historyLine--;
+ LockOutput();
+ cmdline.Remove(0, cmdline.Length);
+ cmdline.Append(history[historyLine]);
+ cp = cmdline.Length;
+ UnlockOutput();
+ break;
+ case ConsoleKey.DownArrow:
+ if (historyLine >= history.Count)
+ break;
+ historyLine++;
+ LockOutput();
+ if (historyLine == history.Count)
+ {
+ cmdline.Remove(0, cmdline.Length);
+ }
+ else
+ {
+ cmdline.Remove(0, cmdline.Length);
+ cmdline.Append(history[historyLine]);
+ }
+ cp = cmdline.Length;
+ UnlockOutput();
+ break;
+ case ConsoleKey.LeftArrow:
+ if (cp > 0)
+ cp--;
+ break;
+ case ConsoleKey.RightArrow:
+ if (cp < cmdline.Length)
+ cp++;
+ break;
+ case ConsoleKey.Enter:
+ System.Console.CursorLeft = 0;
+ y = SetCursorTop(y);
+
+ System.Console.WriteLine("{0}{1}", prompt, cmdline);
+
+ lock (cmdline)
+ {
+ y = -1;
+ }
+
+ if (isCommand)
+ {
+ string[] cmd = Commands.Resolve(Parser.Parse(cmdline.ToString()));
+
+ if (cmd.Length != 0)
+ {
+ int i;
+
+ for (i=0 ; i < cmd.Length ; i++)
+ {
+ if (cmd[i].Contains(" "))
+ cmd[i] = "\"" + cmd[i] + "\"";
+ }
+ AddToHistory(String.Join(" ", cmd));
+ return String.Empty;
+ }
+ }
+
+ AddToHistory(cmdline.ToString());
+ return cmdline.ToString();
+ default:
+ break;
+ }
+ }
+ }
+ }
+ }
+}
diff --git a/OpenSim/Framework/Console/MainConsole.cs b/OpenSim/Framework/Console/MainConsole.cs
index 15df699..b438089 100644
--- a/OpenSim/Framework/Console/MainConsole.cs
+++ b/OpenSim/Framework/Console/MainConsole.cs
@@ -29,9 +29,9 @@ namespace OpenSim.Framework.Console
{
public class MainConsole
{
- private static ConsoleBase instance;
+ private static CommandConsole instance;
- public static ConsoleBase Instance
+ public static CommandConsole Instance
{
get { return instance; }
set { instance = value; }
--
cgit v1.1