diff options
author | UbitUmarov | 2015-09-01 11:43:07 +0100 |
---|---|---|
committer | UbitUmarov | 2015-09-01 11:43:07 +0100 |
commit | fb78b182520fc9bb0f971afd0322029c70278ea6 (patch) | |
tree | b4e30d383938fdeef8c92d1d1c2f44bb61d329bd /OpenSim/Framework/Console/LocalConsole.cs | |
parent | lixo (diff) | |
parent | Mantis #7713: fixed bug introduced by 1st MOSES patch. (diff) | |
download | opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.zip opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.gz opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.bz2 opensim-SC-fb78b182520fc9bb0f971afd0322029c70278ea6.tar.xz |
Merge remote-tracking branch 'os/master'
Diffstat (limited to 'OpenSim/Framework/Console/LocalConsole.cs')
-rw-r--r-- | OpenSim/Framework/Console/LocalConsole.cs | 585 |
1 files changed, 585 insertions, 0 deletions
diff --git a/OpenSim/Framework/Console/LocalConsole.cs b/OpenSim/Framework/Console/LocalConsole.cs new file mode 100644 index 0000000..28293c0 --- /dev/null +++ b/OpenSim/Framework/Console/LocalConsole.cs | |||
@@ -0,0 +1,585 @@ | |||
1 | /* | ||
2 | * Copyright (c) Contributors, http://opensimulator.org/ | ||
3 | * See CONTRIBUTORS.TXT for a full list of copyright holders. | ||
4 | * | ||
5 | * Redistribution and use in source and binary forms, with or without | ||
6 | * modification, are permitted provided that the following conditions are met: | ||
7 | * * Redistributions of source code must retain the above copyright | ||
8 | * notice, this list of conditions and the following disclaimer. | ||
9 | * * Redistributions in binary form must reproduce the above copyright | ||
10 | * notice, this list of conditions and the following disclaimer in the | ||
11 | * documentation and/or other materials provided with the distribution. | ||
12 | * * Neither the name of the OpenSimulator Project nor the | ||
13 | * names of its contributors may be used to endorse or promote products | ||
14 | * derived from this software without specific prior written permission. | ||
15 | * | ||
16 | * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY | ||
17 | * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED | ||
18 | * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE | ||
19 | * DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY | ||
20 | * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES | ||
21 | * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; | ||
22 | * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND | ||
23 | * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
24 | * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | ||
25 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
26 | */ | ||
27 | |||
28 | using System; | ||
29 | using System.Collections.Generic; | ||
30 | using System.Diagnostics; | ||
31 | using System.Reflection; | ||
32 | using System.Text; | ||
33 | using System.Text.RegularExpressions; | ||
34 | using System.Threading; | ||
35 | using System.IO; | ||
36 | using Nini.Config; | ||
37 | using log4net; | ||
38 | |||
39 | namespace OpenSim.Framework.Console | ||
40 | { | ||
41 | /// <summary> | ||
42 | /// A console that uses cursor control and color | ||
43 | /// </summary> | ||
44 | public class LocalConsole : CommandConsole | ||
45 | { | ||
46 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | ||
47 | private string m_historyPath; | ||
48 | private bool m_historyEnable; | ||
49 | |||
50 | // private readonly object m_syncRoot = new object(); | ||
51 | private const string LOGLEVEL_NONE = "(none)"; | ||
52 | |||
53 | // Used to extract categories for colourization. | ||
54 | private Regex m_categoryRegex | ||
55 | = new Regex( | ||
56 | @"^(?<Front>.*?)\[(?<Category>[^\]]+)\]:?(?<End>.*)", RegexOptions.Singleline | RegexOptions.Compiled); | ||
57 | |||
58 | private int m_cursorYPosition = -1; | ||
59 | private int m_cursorXPosition = 0; | ||
60 | private StringBuilder m_commandLine = new StringBuilder(); | ||
61 | private bool m_echo = true; | ||
62 | private List<string> m_history = new List<string>(); | ||
63 | |||
64 | private static readonly ConsoleColor[] Colors = { | ||
65 | // the dark colors don't seem to be visible on some black background terminals like putty :( | ||
66 | //ConsoleColor.DarkBlue, | ||
67 | //ConsoleColor.DarkGreen, | ||
68 | //ConsoleColor.DarkCyan, | ||
69 | //ConsoleColor.DarkMagenta, | ||
70 | //ConsoleColor.DarkYellow, | ||
71 | ConsoleColor.Gray, | ||
72 | //ConsoleColor.DarkGray, | ||
73 | ConsoleColor.Blue, | ||
74 | ConsoleColor.Green, | ||
75 | ConsoleColor.Cyan, | ||
76 | ConsoleColor.Magenta, | ||
77 | ConsoleColor.Yellow | ||
78 | }; | ||
79 | |||
80 | private static ConsoleColor DeriveColor(string input) | ||
81 | { | ||
82 | // it is important to do Abs, hash values can be negative | ||
83 | return Colors[(Math.Abs(input.ToUpper().GetHashCode()) % Colors.Length)]; | ||
84 | } | ||
85 | |||
86 | public LocalConsole(string defaultPrompt, IConfig startupConfig = null) : base(defaultPrompt) | ||
87 | { | ||
88 | |||
89 | if (startupConfig == null) return; | ||
90 | |||
91 | m_historyEnable = startupConfig.GetBoolean("ConsoleHistoryFileEnabled", false); | ||
92 | if (!m_historyEnable) | ||
93 | { | ||
94 | m_log.Info("[LOCAL CONSOLE]: Persistent command line history from file is Disabled"); | ||
95 | return; | ||
96 | } | ||
97 | |||
98 | string m_historyFile = startupConfig.GetString("ConsoleHistoryFile", "OpenSimConsoleHistory.txt"); | ||
99 | int m_historySize = startupConfig.GetInt("ConsoleHistoryFileLines", 100); | ||
100 | m_historyPath = Path.GetFullPath(Path.Combine(Util.configDir(), m_historyFile)); | ||
101 | m_log.InfoFormat("[LOCAL CONSOLE]: Persistent command line history is Enabled, up to {0} lines from file {1}", m_historySize, m_historyPath); | ||
102 | |||
103 | if (File.Exists(m_historyPath)) | ||
104 | { | ||
105 | using (StreamReader history_file = new StreamReader(m_historyPath)) | ||
106 | { | ||
107 | string line; | ||
108 | while ((line = history_file.ReadLine()) != null) | ||
109 | { | ||
110 | m_history.Add(line); | ||
111 | } | ||
112 | } | ||
113 | |||
114 | if (m_history.Count > m_historySize) | ||
115 | { | ||
116 | while (m_history.Count > m_historySize) | ||
117 | m_history.RemoveAt(0); | ||
118 | |||
119 | using (StreamWriter history_file = new StreamWriter(m_historyPath)) | ||
120 | { | ||
121 | foreach (string line in m_history) | ||
122 | { | ||
123 | history_file.WriteLine(line); | ||
124 | } | ||
125 | } | ||
126 | } | ||
127 | m_log.InfoFormat("[LOCAL CONSOLE]: Read {0} lines of command line history from file {1}", m_history.Count, m_historyPath); | ||
128 | } | ||
129 | else | ||
130 | { | ||
131 | m_log.InfoFormat("[LOCAL CONSOLE]: Creating new empty command line history file {0}", m_historyPath); | ||
132 | File.Create(m_historyPath).Dispose(); | ||
133 | } | ||
134 | } | ||
135 | |||
136 | private void AddToHistory(string text) | ||
137 | { | ||
138 | while (m_history.Count >= 100) | ||
139 | m_history.RemoveAt(0); | ||
140 | |||
141 | m_history.Add(text); | ||
142 | if (m_historyEnable) | ||
143 | { | ||
144 | File.AppendAllText(m_historyPath, text + Environment.NewLine); | ||
145 | } | ||
146 | } | ||
147 | |||
148 | /// <summary> | ||
149 | /// Set the cursor row. | ||
150 | /// </summary> | ||
151 | /// | ||
152 | /// <param name="top"> | ||
153 | /// Row to set. If this is below 0, then the row is set to 0. If it is equal to the buffer height or greater | ||
154 | /// then it is set to one less than the height. | ||
155 | /// </param> | ||
156 | /// <returns> | ||
157 | /// The new cursor row. | ||
158 | /// </returns> | ||
159 | private int SetCursorTop(int top) | ||
160 | { | ||
161 | // From at least mono 2.4.2.3, window resizing can give mono an invalid row and column values. If we try | ||
162 | // to set a cursor row position with a currently invalid column, mono will throw an exception. | ||
163 | // Therefore, we need to make sure that the column position is valid first. | ||
164 | int left = System.Console.CursorLeft; | ||
165 | |||
166 | if (left < 0) | ||
167 | { | ||
168 | System.Console.CursorLeft = 0; | ||
169 | } | ||
170 | else | ||
171 | { | ||
172 | int bufferWidth = System.Console.BufferWidth; | ||
173 | |||
174 | // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) | ||
175 | if (bufferWidth > 0 && left >= bufferWidth) | ||
176 | System.Console.CursorLeft = bufferWidth - 1; | ||
177 | } | ||
178 | |||
179 | if (top < 0) | ||
180 | { | ||
181 | top = 0; | ||
182 | } | ||
183 | else | ||
184 | { | ||
185 | int bufferHeight = System.Console.BufferHeight; | ||
186 | |||
187 | // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) | ||
188 | if (bufferHeight > 0 && top >= bufferHeight) | ||
189 | top = bufferHeight - 1; | ||
190 | } | ||
191 | |||
192 | System.Console.CursorTop = top; | ||
193 | |||
194 | return top; | ||
195 | } | ||
196 | |||
197 | /// <summary> | ||
198 | /// Set the cursor column. | ||
199 | /// </summary> | ||
200 | /// | ||
201 | /// <param name="left"> | ||
202 | /// Column to set. If this is below 0, then the column is set to 0. If it is equal to the buffer width or greater | ||
203 | /// then it is set to one less than the width. | ||
204 | /// </param> | ||
205 | /// <returns> | ||
206 | /// The new cursor column. | ||
207 | /// </returns> | ||
208 | private int SetCursorLeft(int left) | ||
209 | { | ||
210 | // From at least mono 2.4.2.3, window resizing can give mono an invalid row and column values. If we try | ||
211 | // to set a cursor column position with a currently invalid row, mono will throw an exception. | ||
212 | // Therefore, we need to make sure that the row position is valid first. | ||
213 | int top = System.Console.CursorTop; | ||
214 | |||
215 | if (top < 0) | ||
216 | { | ||
217 | System.Console.CursorTop = 0; | ||
218 | } | ||
219 | else | ||
220 | { | ||
221 | int bufferHeight = System.Console.BufferHeight; | ||
222 | // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) | ||
223 | if (bufferHeight > 0 && top >= bufferHeight) | ||
224 | System.Console.CursorTop = bufferHeight - 1; | ||
225 | } | ||
226 | |||
227 | if (left < 0) | ||
228 | { | ||
229 | left = 0; | ||
230 | } | ||
231 | else | ||
232 | { | ||
233 | int bufferWidth = System.Console.BufferWidth; | ||
234 | |||
235 | // On Mono 2.4.2.3 (and possibly above), the buffer value is sometimes erroneously zero (Mantis 4657) | ||
236 | if (bufferWidth > 0 && left >= bufferWidth) | ||
237 | left = bufferWidth - 1; | ||
238 | } | ||
239 | |||
240 | System.Console.CursorLeft = left; | ||
241 | |||
242 | return left; | ||
243 | } | ||
244 | |||
245 | private void Show() | ||
246 | { | ||
247 | lock (m_commandLine) | ||
248 | { | ||
249 | if (m_cursorYPosition == -1 || System.Console.BufferWidth == 0) | ||
250 | return; | ||
251 | |||
252 | int xc = prompt.Length + m_cursorXPosition; | ||
253 | int new_x = xc % System.Console.BufferWidth; | ||
254 | int new_y = m_cursorYPosition + xc / System.Console.BufferWidth; | ||
255 | int end_y = m_cursorYPosition + (m_commandLine.Length + prompt.Length) / System.Console.BufferWidth; | ||
256 | |||
257 | if (end_y >= System.Console.BufferHeight) // wrap | ||
258 | { | ||
259 | m_cursorYPosition--; | ||
260 | new_y--; | ||
261 | SetCursorLeft(0); | ||
262 | SetCursorTop(System.Console.BufferHeight - 1); | ||
263 | System.Console.WriteLine(" "); | ||
264 | } | ||
265 | |||
266 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
267 | SetCursorLeft(0); | ||
268 | |||
269 | if (m_echo) | ||
270 | System.Console.Write("{0}{1}", prompt, m_commandLine); | ||
271 | else | ||
272 | System.Console.Write("{0}", prompt); | ||
273 | |||
274 | SetCursorTop(new_y); | ||
275 | SetCursorLeft(new_x); | ||
276 | } | ||
277 | } | ||
278 | |||
279 | public override void LockOutput() | ||
280 | { | ||
281 | Monitor.Enter(m_commandLine); | ||
282 | try | ||
283 | { | ||
284 | if (m_cursorYPosition != -1) | ||
285 | { | ||
286 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
287 | System.Console.CursorLeft = 0; | ||
288 | |||
289 | int count = m_commandLine.Length + prompt.Length; | ||
290 | |||
291 | while (count-- > 0) | ||
292 | System.Console.Write(" "); | ||
293 | |||
294 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
295 | SetCursorLeft(0); | ||
296 | } | ||
297 | } | ||
298 | catch (Exception) | ||
299 | { | ||
300 | } | ||
301 | } | ||
302 | |||
303 | public override void UnlockOutput() | ||
304 | { | ||
305 | if (m_cursorYPosition != -1) | ||
306 | { | ||
307 | m_cursorYPosition = System.Console.CursorTop; | ||
308 | Show(); | ||
309 | } | ||
310 | Monitor.Exit(m_commandLine); | ||
311 | } | ||
312 | |||
313 | private void WriteColorText(ConsoleColor color, string sender) | ||
314 | { | ||
315 | try | ||
316 | { | ||
317 | lock (this) | ||
318 | { | ||
319 | try | ||
320 | { | ||
321 | System.Console.ForegroundColor = color; | ||
322 | System.Console.Write(sender); | ||
323 | System.Console.ResetColor(); | ||
324 | } | ||
325 | catch (ArgumentNullException) | ||
326 | { | ||
327 | // Some older systems dont support coloured text. | ||
328 | System.Console.WriteLine(sender); | ||
329 | } | ||
330 | } | ||
331 | } | ||
332 | catch (ObjectDisposedException) | ||
333 | { | ||
334 | } | ||
335 | } | ||
336 | |||
337 | private void WriteLocalText(string text, string level) | ||
338 | { | ||
339 | string outText = text; | ||
340 | |||
341 | if (level != LOGLEVEL_NONE) | ||
342 | { | ||
343 | MatchCollection matches = m_categoryRegex.Matches(text); | ||
344 | |||
345 | if (matches.Count == 1) | ||
346 | { | ||
347 | outText = matches[0].Groups["End"].Value; | ||
348 | System.Console.Write(matches[0].Groups["Front"].Value); | ||
349 | |||
350 | System.Console.Write("["); | ||
351 | WriteColorText(DeriveColor(matches[0].Groups["Category"].Value), | ||
352 | matches[0].Groups["Category"].Value); | ||
353 | System.Console.Write("]:"); | ||
354 | } | ||
355 | else | ||
356 | { | ||
357 | outText = outText.Trim(); | ||
358 | } | ||
359 | } | ||
360 | |||
361 | if (level == "error") | ||
362 | WriteColorText(ConsoleColor.Red, outText); | ||
363 | else if (level == "warn") | ||
364 | WriteColorText(ConsoleColor.Yellow, outText); | ||
365 | else | ||
366 | System.Console.Write(outText); | ||
367 | |||
368 | System.Console.WriteLine(); | ||
369 | } | ||
370 | |||
371 | public override void Output(string text) | ||
372 | { | ||
373 | Output(text, LOGLEVEL_NONE); | ||
374 | } | ||
375 | |||
376 | public override void Output(string text, string level) | ||
377 | { | ||
378 | FireOnOutput(text); | ||
379 | |||
380 | lock (m_commandLine) | ||
381 | { | ||
382 | if (m_cursorYPosition == -1) | ||
383 | { | ||
384 | WriteLocalText(text, level); | ||
385 | |||
386 | return; | ||
387 | } | ||
388 | |||
389 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
390 | SetCursorLeft(0); | ||
391 | |||
392 | int count = m_commandLine.Length + prompt.Length; | ||
393 | |||
394 | while (count-- > 0) | ||
395 | System.Console.Write(" "); | ||
396 | |||
397 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
398 | SetCursorLeft(0); | ||
399 | |||
400 | WriteLocalText(text, level); | ||
401 | |||
402 | m_cursorYPosition = System.Console.CursorTop; | ||
403 | |||
404 | Show(); | ||
405 | } | ||
406 | } | ||
407 | |||
408 | private bool ContextHelp() | ||
409 | { | ||
410 | string[] words = Parser.Parse(m_commandLine.ToString()); | ||
411 | |||
412 | bool trailingSpace = m_commandLine.ToString().EndsWith(" "); | ||
413 | |||
414 | // Allow ? through while typing a URI | ||
415 | // | ||
416 | if (words.Length > 0 && words[words.Length-1].StartsWith("http") && !trailingSpace) | ||
417 | return false; | ||
418 | |||
419 | string[] opts = Commands.FindNextOption(words, trailingSpace); | ||
420 | |||
421 | if (opts[0].StartsWith("Command help:")) | ||
422 | Output(opts[0]); | ||
423 | else | ||
424 | Output(String.Format("Options: {0}", String.Join(" ", opts))); | ||
425 | |||
426 | return true; | ||
427 | } | ||
428 | |||
429 | public override string ReadLine(string p, bool isCommand, bool e) | ||
430 | { | ||
431 | m_cursorXPosition = 0; | ||
432 | prompt = p; | ||
433 | m_echo = e; | ||
434 | int historyLine = m_history.Count; | ||
435 | |||
436 | SetCursorLeft(0); // Needed for mono | ||
437 | System.Console.Write(" "); // Needed for mono | ||
438 | |||
439 | lock (m_commandLine) | ||
440 | { | ||
441 | m_cursorYPosition = System.Console.CursorTop; | ||
442 | m_commandLine.Remove(0, m_commandLine.Length); | ||
443 | } | ||
444 | |||
445 | while (true) | ||
446 | { | ||
447 | Show(); | ||
448 | |||
449 | ConsoleKeyInfo key = System.Console.ReadKey(true); | ||
450 | char enteredChar = key.KeyChar; | ||
451 | |||
452 | if (!Char.IsControl(enteredChar)) | ||
453 | { | ||
454 | if (m_cursorXPosition >= 318) | ||
455 | continue; | ||
456 | |||
457 | if (enteredChar == '?' && isCommand) | ||
458 | { | ||
459 | if (ContextHelp()) | ||
460 | continue; | ||
461 | } | ||
462 | |||
463 | m_commandLine.Insert(m_cursorXPosition, enteredChar); | ||
464 | m_cursorXPosition++; | ||
465 | } | ||
466 | else | ||
467 | { | ||
468 | switch (key.Key) | ||
469 | { | ||
470 | case ConsoleKey.Backspace: | ||
471 | if (m_cursorXPosition == 0) | ||
472 | break; | ||
473 | m_commandLine.Remove(m_cursorXPosition-1, 1); | ||
474 | m_cursorXPosition--; | ||
475 | |||
476 | SetCursorLeft(0); | ||
477 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
478 | |||
479 | if (m_echo) | ||
480 | System.Console.Write("{0}{1} ", prompt, m_commandLine); | ||
481 | else | ||
482 | System.Console.Write("{0}", prompt); | ||
483 | |||
484 | break; | ||
485 | case ConsoleKey.Delete: | ||
486 | if (m_cursorXPosition == m_commandLine.Length) | ||
487 | break; | ||
488 | |||
489 | m_commandLine.Remove(m_cursorXPosition, 1); | ||
490 | |||
491 | SetCursorLeft(0); | ||
492 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
493 | |||
494 | if (m_echo) | ||
495 | System.Console.Write("{0}{1} ", prompt, m_commandLine); | ||
496 | else | ||
497 | System.Console.Write("{0}", prompt); | ||
498 | |||
499 | break; | ||
500 | case ConsoleKey.End: | ||
501 | m_cursorXPosition = m_commandLine.Length; | ||
502 | break; | ||
503 | case ConsoleKey.Home: | ||
504 | m_cursorXPosition = 0; | ||
505 | break; | ||
506 | case ConsoleKey.UpArrow: | ||
507 | if (historyLine < 1) | ||
508 | break; | ||
509 | historyLine--; | ||
510 | LockOutput(); | ||
511 | m_commandLine.Remove(0, m_commandLine.Length); | ||
512 | m_commandLine.Append(m_history[historyLine]); | ||
513 | m_cursorXPosition = m_commandLine.Length; | ||
514 | UnlockOutput(); | ||
515 | break; | ||
516 | case ConsoleKey.DownArrow: | ||
517 | if (historyLine >= m_history.Count) | ||
518 | break; | ||
519 | historyLine++; | ||
520 | LockOutput(); | ||
521 | if (historyLine == m_history.Count) | ||
522 | { | ||
523 | m_commandLine.Remove(0, m_commandLine.Length); | ||
524 | } | ||
525 | else | ||
526 | { | ||
527 | m_commandLine.Remove(0, m_commandLine.Length); | ||
528 | m_commandLine.Append(m_history[historyLine]); | ||
529 | } | ||
530 | m_cursorXPosition = m_commandLine.Length; | ||
531 | UnlockOutput(); | ||
532 | break; | ||
533 | case ConsoleKey.LeftArrow: | ||
534 | if (m_cursorXPosition > 0) | ||
535 | m_cursorXPosition--; | ||
536 | break; | ||
537 | case ConsoleKey.RightArrow: | ||
538 | if (m_cursorXPosition < m_commandLine.Length) | ||
539 | m_cursorXPosition++; | ||
540 | break; | ||
541 | case ConsoleKey.Enter: | ||
542 | SetCursorLeft(0); | ||
543 | m_cursorYPosition = SetCursorTop(m_cursorYPosition); | ||
544 | |||
545 | System.Console.WriteLine(); | ||
546 | //Show(); | ||
547 | |||
548 | lock (m_commandLine) | ||
549 | { | ||
550 | m_cursorYPosition = -1; | ||
551 | } | ||
552 | |||
553 | string commandLine = m_commandLine.ToString(); | ||
554 | |||
555 | if (isCommand) | ||
556 | { | ||
557 | string[] cmd = Commands.Resolve(Parser.Parse(commandLine)); | ||
558 | |||
559 | if (cmd.Length != 0) | ||
560 | { | ||
561 | int index; | ||
562 | |||
563 | for (index=0 ; index < cmd.Length ; index++) | ||
564 | { | ||
565 | if (cmd[index].Contains(" ")) | ||
566 | cmd[index] = "\"" + cmd[index] + "\""; | ||
567 | } | ||
568 | AddToHistory(String.Join(" ", cmd)); | ||
569 | return String.Empty; | ||
570 | } | ||
571 | } | ||
572 | |||
573 | // If we're not echoing to screen (e.g. a password) then we probably don't want it in history | ||
574 | if (m_echo && commandLine != "") | ||
575 | AddToHistory(commandLine); | ||
576 | |||
577 | return commandLine; | ||
578 | default: | ||
579 | break; | ||
580 | } | ||
581 | } | ||
582 | } | ||
583 | } | ||
584 | } | ||
585 | } | ||