source: trunk/eraser/Eraser/Program.ConsoleProgram.cs @ 2671

Revision 2671, 5.1 KB checked in by lowjoel, 3 years ago (diff)

Don't crash when the user enters an invalid action on the command line.

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Rev URL
Line 
1/*
2 * $Id$
3 * Copyright 2008-2012 The Eraser Project
4 * Original Author: Joel Low <lowjoel@users.sourceforge.net>
5 * Modified By:
6 *
7 * This file is part of Eraser.
8 *
9 * Eraser is free software: you can redistribute it and/or modify it under the
10 * terms of the GNU General Public License as published by the Free Software
11 * Foundation, either version 3 of the License, or (at your option) any later
12 * version.
13 *
14 * Eraser is distributed in the hope that it will be useful, but WITHOUT ANY
15 * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
16 * A PARTICULAR PURPOSE. See the GNU General Public License for more details.
17 *
18 * A copy of the GNU General Public License can be found at
19 * <http://www.gnu.org/licenses/>.
20 */
21
22using System;
23using System.Collections.Generic;
24using System.Text;
25using System.IO;
26
27using ComLib.Arguments;
28
29using Eraser.Manager;
30using Eraser.Util;
31
32namespace Eraser
33{
34    internal static partial class Program
35    {
36        /// <summary>
37        /// Manages and runs a console program. This allows the program to switch
38        /// between console and GUI subsystems at runtime. This class will manage
39        /// the creation of a console window and destruction of the window upon
40        /// exit of the program.
41        /// </summary>
42        class ConsoleProgram : IDisposable
43        {
44            /// <summary>
45            /// Constructor.
46            /// </summary>
47            /// <param name="commandLine">The raw command line arguments passed to the program.</param>
48            public ConsoleProgram(string[] commandLine)
49            {
50                CommandLine = commandLine;
51                Handlers = new Dictionary<string, ConsoleActionData>();
52
53                //Try to parse the command line for a Quiet argument.
54                Arguments = new ConsoleArguments();
55                Args.Parse(commandLine, CommandLinePrefixes, CommandLineSeparators, Arguments);
56
57                //Create the console window if we don't have the quiet argument.
58                if (!Arguments.Quiet)
59                    ConsoleWindow = new ConsoleWindow();
60            }
61
62            #region IDisposable Members
63            ~ConsoleProgram()
64            {
65                Dispose(false);
66            }
67
68            public void Dispose()
69            {
70                Dispose(true);
71                GC.SuppressFinalize(this);
72            }
73
74            protected virtual void Dispose(bool disposing)
75            {
76                if (ConsoleWindow == null)
77                    return;
78
79                //Flush the buffered output to the console
80                Console.Out.Flush();
81
82                //Don't ask for a key to press if the user specified Quiet.
83                if (!Arguments.Quiet)
84                {
85                    Console.Write("\nPress any key to continue . . . ");
86                    Console.Out.Flush();
87                    Console.ReadKey(true);
88
89                    if (disposing)
90                        ConsoleWindow.Dispose();
91                }
92
93                ConsoleWindow = null;
94            }
95            #endregion
96
97            /// <summary>
98            /// Runs the program, analogous to System.Windows.Forms.Application.Run.
99            /// </summary>
100            public void Run()
101            {
102                //Check that we've got an action corresponding to one the user requested.
103                if (!Handlers.ContainsKey(Arguments.Action))
104                    throw new ArgumentException(S._("Unknown action {0}", Arguments.Action));
105
106                //Re-parse the command line arguments as arguments for the given action.
107                ConsoleActionData data = Handlers[Arguments.Action];
108                ConsoleArguments arguments = data.Arguments;
109                ComLib.BoolMessageItem<Args> parseResult = Args.Parse(CommandLine,
110                    CommandLinePrefixes, CommandLineSeparators, arguments);
111                if (!parseResult.Success)
112                    throw new ArgumentException(parseResult.Message);
113
114                //Remove the action from the positional arguments before sending it to the handler
115                System.Diagnostics.Debug.Assert(Arguments.Action == parseResult.Item.Positional[0]);
116                parseResult.Item.Positional.RemoveAt(0);
117                arguments.PositionalArguments = parseResult.Item.Positional;
118
119                //Then invoke the handler for this action.
120                data.Handler(arguments);
121            }
122
123            /// <summary>
124            /// The prototype of an action handler in the class which executes an
125            /// action as specified in the command line.
126            /// </summary>
127            /// <param name="handler">The <see cref="Program.ConsoleHandler"/> instance
128            /// that contains the parsed command line arguments.</param>
129            public delegate void ActionHandler(ConsoleArguments handler);
130
131            /// <summary>
132            /// Matches an action to a handler.
133            /// </summary>
134            public Dictionary<string, ConsoleActionData> Handlers { get; private set; }
135
136            /// <summary>
137            /// The Console Window created by this object.
138            /// </summary>
139            private ConsoleWindow ConsoleWindow;
140
141            /// <summary>
142            /// The command line arguments the program was started with.
143            /// </summary>
144            private string[] CommandLine;
145
146            /// <summary>
147            /// Stores the common Console arguments which were given on the command line.
148            /// </summary>
149            private ConsoleArguments Arguments;
150        }
151
152        /// <summary>
153        /// Stores information about an Action invoked from the command line.
154        /// </summary>
155        class ConsoleActionData
156        {
157            public ConsoleActionData(ConsoleProgram.ActionHandler handler,
158                ConsoleArguments arguments)
159            {
160                Handler = handler;
161                Arguments = arguments;
162            }
163
164            /// <summary>
165            /// The Handler for this action.
166            /// </summary>
167            public ConsoleProgram.ActionHandler Handler { get; private set; }
168
169            /// <summary>
170            /// The <see cref="ConsoleArguments"/> object receiving arguments from the command line.
171            /// </summary>
172            public ConsoleArguments Arguments { get; private set; }
173        }
174    }
175}
Note: See TracBrowser for help on using the repository browser.