2001-06-13 Miguel de Icaza <miguel@ximian.com>
[mono.git] / mcs / mcs / driver.cs
1 //\r
2 // driver.cs: The compiler command line driver.\r
3 //\r
4 // Author: Miguel de Icaza (miguel@gnu.org)\r
5 //\r
6 // Licensed under the terms of the GNU GPL\r
7 //\r
8 // (C) 2001 Ximian, Inc (http://www.ximian.com)\r
9 //\r
10 \r
11 namespace CSC\r
12 {\r
13         using System;\r
14         using System.Reflection;\r
15         using System.Reflection.Emit;\r
16         using System.Collections;\r
17         using System.IO;\r
18         using CIR;\r
19         using Generator;\r
20         using CSC;\r
21 \r
22         /// <summary>\r
23         ///    Summary description for Class1.\r
24         /// </summary>\r
25         public class Driver\r
26         {\r
27                 //\r
28                 // Assemblies references to be linked.   Initialized with\r
29                 // mscorlib.dll here.\r
30                 ArrayList references;\r
31 \r
32                 // Lookup paths\r
33                 ArrayList link_paths;\r
34 \r
35                 // Our parser context.\r
36                 Tree context;\r
37                 \r
38                 bool yacc_verbose = false;\r
39 \r
40                 int error_count = 0;\r
41 \r
42                 public int parse (Tree context, string input_file)\r
43                 {\r
44                         CSharpParser parser;\r
45                         System.IO.Stream input;\r
46                         int errors;\r
47                         \r
48                         try {\r
49                                 input = System.IO.File.OpenRead (input_file);\r
50                         } catch {\r
51                                 return 1;\r
52                         }\r
53 \r
54                         parser = new CSharpParser (context, input_file, input);\r
55                         parser.yacc_verbose = yacc_verbose;\r
56                         try {\r
57                                 errors = parser.parse ();\r
58                         } catch (Exception ex) {\r
59                                 Console.WriteLine (ex);\r
60                                 Console.WriteLine ("Compilation aborted");\r
61                                 return 1;\r
62                         }\r
63                         \r
64                         return errors;\r
65                 }\r
66                 \r
67                 public void Usage ()\r
68                 {\r
69                         Console.WriteLine (\r
70                                 "compiler [-v] [-t tree] [-o output] [-L path] [-r reference] sources.cs\n" +\r
71                                 "-v  Verbose parsing\n"+\r
72                                 "-o  Specifies output file\n" +\r
73                                 "-L  Specifies path for loading assemblies\n" +\r
74                                 "-r  References an assembly\n");\r
75                         \r
76                 }\r
77 \r
78                 public IGenerator lookup_output (string name)\r
79                 {\r
80                         if (name == "tree")\r
81                                 return new Generator.TreeDump ();\r
82                         if (name == "il")\r
83                                 return new MSIL.Generator ();\r
84                         \r
85                         return null;\r
86                 }\r
87 \r
88                 public static void error (string msg)\r
89                 {\r
90                         Console.WriteLine ("Error: " + msg);\r
91                 }\r
92 \r
93                 public static void notice (string msg)\r
94                 {\r
95                         Console.WriteLine (msg);\r
96                 }\r
97                 \r
98                 public static int Main(string[] args)\r
99                 {\r
100                         Driver driver = new Driver (args);\r
101 \r
102                         return driver.error_count;\r
103                 }\r
104 \r
105                 public int LoadAssembly (string assembly)\r
106                 {\r
107                         Assembly a;\r
108 \r
109                         foreach (string dir in link_paths){\r
110                                 string full_path = dir + "\\" + assembly;\r
111 \r
112                                 try {\r
113                                         a = Assembly.Load (full_path);\r
114                                 } catch (FileNotFoundException) {\r
115                                         error ("// File not found: " + full_path);\r
116                                         return 1;\r
117                                 } catch (BadImageFormatException) {\r
118                                         error ("// Bad file format: " + full_path);\r
119                                         return 1;\r
120                                 }\r
121 \r
122                                 context.AddAssembly (a);\r
123                         }\r
124                         return 0;\r
125                 }\r
126                 \r
127                 public int LoadReferences ()\r
128                 {\r
129                         int errors = 0;\r
130                         \r
131                         foreach (string r in references){\r
132                                 errors += LoadAssembly (r);\r
133                         }\r
134 \r
135                         return errors;\r
136                 }\r
137 \r
138                 \r
139                 public Driver (string [] args)\r
140                 {\r
141                         Stream output_stream = Console.OpenStandardOutput ();\r
142                         IGenerator generator = null;\r
143                         int errors = 0, i;\r
144 \r
145                         context = new Tree ();\r
146                         references = new ArrayList ();\r
147                         link_paths = new ArrayList ();\r
148 \r
149                         //\r
150                         // Setup defaults\r
151                         //\r
152                         references.Add ("mscorlib.dll");\r
153                         link_paths.Add ("C://WINNT/Microsoft.Net/Framework/v1.0.2204");\r
154                         \r
155                         for (i = 0; i < args.Length; i++){\r
156                                 string arg = args [i];\r
157                                 \r
158                                 if (arg.StartsWith ("-")){\r
159                                         if (arg.StartsWith ("-v")){\r
160                                                 yacc_verbose = true;\r
161                                                 continue;\r
162                                         }\r
163 \r
164                                         if (arg.StartsWith ("-t")){\r
165                                                 generator = lookup_output (args [++i]);\r
166                                                 continue;\r
167                                         }\r
168 \r
169                                         if (arg.StartsWith ("-z")){\r
170                                                 generator.ParseOptions (args [++i]);\r
171                                                 continue;\r
172                                         }\r
173                                         \r
174                                         if (arg.StartsWith ("-o")){\r
175                                                 try {\r
176                                                         output_stream = File.Create (args [++i]);\r
177                                                 } catch (Exception){\r
178                                                         error ("Could not write to `"+args [i]);\r
179                                                         error_count++;\r
180                                                         return;\r
181                                                 }\r
182                                                 continue;\r
183                                         }\r
184 \r
185                                         if (arg.StartsWith ("-r")){\r
186                                                 references.Add (args [++i]);\r
187                                                 continue;\r
188                                         }\r
189 \r
190                                         if (arg.StartsWith ("-L")){\r
191                                                 link_paths.Add (args [++i]);\r
192                                                 continue;\r
193                                         }\r
194 \r
195                                         Usage ();\r
196                                         error_count++;\r
197                                         return;\r
198                                 }\r
199                                 \r
200                                 if (!arg.EndsWith (".cs")){\r
201                                         error ("Do not know how to compile " + arg);\r
202                                         errors++;\r
203                                         continue;\r
204                                 }\r
205 \r
206                                 errors += parse (context, arg);\r
207                         }\r
208                         if (errors > 0)\r
209                                 error ("// Parsing failed");\r
210                         else\r
211                                 notice ("// Parsing successful");                               \r
212 \r
213                         //\r
214                         // Load assemblies required\r
215                         //\r
216                         errors += LoadReferences ();\r
217 \r
218                         if (errors > 0)\r
219                                 error ("// Could not load one or more assemblies");\r
220                         else\r
221                                 notice ("// Assemblies loaded");\r
222 \r
223 \r
224                         errors += context.BuilderInit ("Module", "Module.exe");\r
225 \r
226                         //\r
227                         // Name resolution on the tree.\r
228                         //\r
229                         errors += context.Resolve ();\r
230                                                    \r
231                         //\r
232                         // Code generation from the tree\r
233                         //\r
234                         if (generator != null){\r
235                                 StreamWriter output = new StreamWriter (output_stream);\r
236                                 \r
237                                 errors += generator.GenerateFromTree (context, output);\r
238 \r
239                                 if (errors > 0)\r
240                                         error ("// Compilation failed");\r
241                                 else\r
242                                         notice ("// Compilation successful");\r
243 \r
244                                 output.Flush ();\r
245                                 output.Close ();\r
246                         }\r
247 \r
248                         error_count = errors;\r
249                 }\r
250 \r
251         }\r
252 }\r
253 \r