File: Main.cs

package info (click to toggle)
mono-debugger 0.60%2Bdfsg-4
  • links: PTS, VCS
  • area: main
  • in suites: lenny
  • size: 9,556 kB
  • ctags: 22,787
  • sloc: ansic: 99,407; cs: 42,429; sh: 9,192; makefile: 376
file content (253 lines) | stat: -rw-r--r-- 6,039 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
using System;
using System.IO;
using System.Configuration;
using ST = System.Threading;
using System.Runtime.InteropServices;

using Mono.Debugger;
using Mono.Debugger.Backend;

namespace Mono.Debugger.Frontend
{
	public class CommandLineInterpreter
	{
		Interpreter interpreter;
		DebuggerEngine engine;
		LineParser parser;
		const string prompt = "(mdb) ";
		int line = 0;

		bool is_inferior_main;
		ST.Thread command_thread;
		ST.Thread main_thread;

		[DllImport("monodebuggerserver")]
		static extern int mono_debugger_server_static_init ();

		[DllImport("monodebuggerserver")]
		static extern int mono_debugger_server_get_pending_sigint ();

		static CommandLineInterpreter ()
		{
			mono_debugger_server_static_init ();
		}

		internal CommandLineInterpreter (bool is_interactive, DebuggerConfiguration config,
						 DebuggerOptions options)
		{
			if (options.HasDebugFlags)
				Report.Initialize (options.DebugOutput, options.DebugFlags);
			else
				Report.Initialize ();

			interpreter = new Interpreter (is_interactive, config, options);
			engine = interpreter.DebuggerEngine;
			parser = new LineParser (engine);

			main_thread = new ST.Thread (new ST.ThreadStart (main_thread_main));
			main_thread.IsBackground = true;

			command_thread = new ST.Thread (new ST.ThreadStart (command_thread_main));
			command_thread.IsBackground = true;
		}

		public CommandLineInterpreter (Interpreter interpreter)
		{
			this.interpreter = interpreter;
			this.engine = interpreter.DebuggerEngine;
			parser = new LineParser (engine);

			main_thread = new ST.Thread (new ST.ThreadStart (main_thread_main));
			main_thread.IsBackground = true;

			command_thread = new ST.Thread (new ST.ThreadStart (command_thread_main));
			command_thread.IsBackground = true;
		}

		public void MainLoop ()
		{
			string s;
			bool is_complete = true;

			parser.Reset ();
			while ((s = ReadInput (is_complete)) != null) {
				parser.Append (s);
				if (parser.IsComplete ()){
					interpreter.ClearInterrupt ();
					parser.Execute ();
					parser.Reset ();
					is_complete = true;
				} else
					is_complete = false;
			}
		}

		void main_thread_main ()
		{
			while (true) {
				try {
					interpreter.ClearInterrupt ();
					MainLoop ();
					if (is_inferior_main)
						break;
				} catch (ST.ThreadAbortException) {
					ST.Thread.ResetAbort ();
				}
			}
		}

		protected void RunMainLoop ()
		{
			is_inferior_main = false;

			command_thread.Start ();

			try {
				if (interpreter.Options.StartTarget)
					interpreter.Start ();

				main_thread.Start ();
				main_thread.Join ();
			} catch (ScriptingException ex) {
				interpreter.Error (ex);
			} catch (TargetException ex) {
				interpreter.Error (ex);
			} catch (Exception ex) {
				interpreter.Error ("ERROR: {0}", ex);
			} finally {
				interpreter.Exit ();
			}
		}

		public void RunInferiorMainLoop ()
		{
			is_inferior_main = true;

			command_thread.Start ();

			TextReader old_stdin = Console.In;
			TextWriter old_stdout = Console.Out;
			TextWriter old_stderr = Console.Error;

			StreamReader stdin_reader = new StreamReader (Console.OpenStandardInput ());

			StreamWriter stdout_writer = new StreamWriter (Console.OpenStandardOutput ());
			stdout_writer.AutoFlush = true;

			StreamWriter stderr_writer = new StreamWriter (Console.OpenStandardError ());
			stderr_writer.AutoFlush = true;

			Console.SetIn (stdin_reader);
			Console.SetOut (stdout_writer);
			Console.SetError (stderr_writer);

			bool old_is_script = interpreter.IsScript;
			bool old_is_interactive = interpreter.IsInteractive;

			interpreter.IsScript = false;
			interpreter.IsInteractive = true;

			Console.WriteLine ();

			try {
				main_thread.Start ();
				main_thread.Join ();
			} catch (ScriptingException ex) {
				interpreter.Error (ex);
			} catch (TargetException ex) {
				interpreter.Error (ex);
			} catch (Exception ex) {
				interpreter.Error ("ERROR: {0}", ex);
			} finally {
				Console.WriteLine ();

				Console.SetIn (old_stdin);
				Console.SetOut (old_stdout);
				Console.SetError (old_stderr);
				interpreter.IsScript = old_is_script;
				interpreter.IsInteractive = old_is_interactive;
			}

			command_thread.Abort ();
		}

		public string ReadInput (bool is_complete)
		{
			++line;
		again:
			string result;
			string the_prompt = is_complete ? prompt : "... ";
			if (interpreter.IsScript) {
				Console.Write (the_prompt);
				result = Console.ReadLine ();
				if (result == null)
					return null;
				if (result != "") {
					;
				} else if (is_complete) {
					engine.Repeat ();
					goto again;
				}
				return result;
			} else {
				result = GnuReadLine.ReadLine (the_prompt);
				if (result == null)
					return null;
				if (result != "")
					GnuReadLine.AddHistory (result);
				else if (is_complete) {
					engine.Repeat ();
					goto again;
				}
				return result;
			}
		}

		public void Error (int pos, string message)
		{
			if (interpreter.Options.IsScript) {
				// If we're reading from a script, abort.
				Console.Write ("ERROR in line {0}, column {1}: ", line, pos);
				Console.WriteLine (message);
				Environment.Exit (1);
			}
			else {
				string prefix = new String (' ', pos + prompt.Length);
				Console.WriteLine ("{0}^", prefix);
				Console.Write ("ERROR: ");
				Console.WriteLine (message);
			}
		}

		void command_thread_main ()
		{
			do {
				Semaphore.Wait ();
				if (mono_debugger_server_get_pending_sigint () == 0)
					continue;

				if (interpreter.Interrupt () > 2)
					main_thread.Abort ();
			} while (true);
		}

		public static void Main (string[] args)
		{
			bool is_terminal = GnuReadLine.IsTerminal (0);

			DebuggerConfiguration config = new DebuggerConfiguration ();
			config.LoadConfiguration ();

			DebuggerOptions options = DebuggerOptions.ParseCommandLine (args);

			Console.WriteLine ("Mono Debugger");

			CommandLineInterpreter interpreter = new CommandLineInterpreter (
				is_terminal, config, options);

			interpreter.RunMainLoop ();

			config.SaveConfiguration ();
		}
	}
}