blob: cec0c485e0ccfac9ee792d532ea677df93b2e8ac [file] [log] [blame] [raw]
//
// Driver.cs
//
// Author:
// Jb Evain (jbevain@gmail.com)
//
// (C) 2005 Jb Evain
//
// Permission is hereby granted, free of charge, to any person obtaining
// a copy of this software and associated documentation files (the
// "Software"), to deal in the Software without restriction, including
// without limitation the rights to use, copy, modify, merge, publish,
// distribute, sublicense, and/or sell copies of the Software, and to
// permit persons to whom the Software is furnished to do so, subject to
// the following conditions:
//
// The above copyright notice and this permission notice shall be
// included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
//
namespace Mono.Disassembler {
using System;
using System.IO;
using System.Reflection;
using System.Text;
using Mono.Cecil;
class Driver {
enum Output {
Gui,
File,
Console
}
enum OutputEncoding {
ASCII,
UTF8,
Unicode
}
static void Main (string [] args)
{
Driver drv = new Driver (args);
drv.Run ();
Environment.Exit (0);
}
string [] m_args;
Output m_output = Output.Console;
OutputEncoding m_encoding = OutputEncoding.UTF8;
string m_assembly;
string m_outputFile;
string m_error;
bool m_no_alias = false;
Driver (string [] args)
{
m_args = args;
}
void Run ()
{
try {
Parse (m_args);
switch (m_output) {
case Output.Gui:
throw new NotImplementedException ("GUI is not implemented");
case Output.Console:
WriteDisassembly (Console.Out);
break;
case Output.File:
FileStream fs = new FileStream (m_outputFile, FileMode.Create, FileAccess.Write, FileShare.None);
Encoding enc = null;
if (m_encoding == OutputEncoding.Unicode)
enc = Encoding.Unicode;
else if (m_encoding == OutputEncoding.UTF8)
enc = Encoding.UTF8;
else
enc = Encoding.ASCII;
using (StreamWriter sw = new StreamWriter (fs, enc))
WriteDisassembly (sw);
break;
}
} catch (Exception e) {
m_error = e.ToString ();
Usage ();
}
}
void WriteDisassembly (TextWriter writer)
{
CilWriter cw = new CilWriter (writer);
StructureDisassembler sd = new StructureDisassembler ();
sd.NoAlias = m_no_alias;
sd.DisassembleAssembly (AssemblyFactory.GetAssembly (m_assembly), cw);
}
string AssemblyName {
get { return m_assembly; }
set {
if (m_assembly != null) {
m_error = "Multiple input files specified !";
return;
}
m_assembly = value;
if (!File.Exists (m_assembly)) {
m_error = "Specified file does not exists !";
}
}
}
void SetOutputFile(String filename) {
m_output = Output.File;
m_outputFile = filename;
}
void Parse (string [] args)
{
//string cmd_arg;
//foreach (string command in args) {
for(int i=0; i<args.Length; i++) {
String command = args[i];
/*
if (cmd [0] != '-' && cmd [0] != '/') {
AssemblyName = cmd;
continue;
}
switch (GetCommand (cmd, out cmd_arg)) {
case "text":
m_output = Output.Console;
break;
case "output":
m_output = Output.File;
m_outputFile = cmd_arg;
break;
case "utf8":
m_encoding = OutputEncoding.UTF8;
break;
case "unicode":
m_encoding = OutputEncoding.Unicode;
break;
case "-about":
About ();
break;
case "-version":
Version ();
break;
default:
if (cmd [0] == '/')
//FIXME: This is only for unix
AssemblyName = cmd;
break;
}
*/
if(command.Length > 1 && command[0] == '-') {
if(command[1] == '-') {
if(command.Length == 2) {
if(++i == args.Length) break;
if(i + 1 < args.Length) {
m_error = "Multiple input files specified !";
break;
}
AssemblyName = args[i];
return;
}
String long_option = command.Substring(2);
switch(long_option) {
case "about":
About();
break;
case "version":
Version();
break;
case "output":
if(++i == args.Length) {
Console.Error.WriteLine("Option --output require an argument");
Environment.Exit(1);
}
SetOutputFile(args[i]);
break;
case "no-alias":
m_no_alias = true;
break;
case "help":
case "usage":
Usage();
return;
default:
Console.Error.WriteLine("Unknown option '{0}'", command);
Environment.Exit(1);
return;
}
} else {
if(command.Length > 2) {
Console.Error.WriteLine("Unknown option '{0}'", command);
Environment.Exit(1);
}
switch(command[1]) {
case 'o':
if(++i == args.Length) {
Console.Error.WriteLine("Option -o require an argument");
Environment.Exit(1);
}
SetOutputFile(args[i]);
break;
default:
Console.Error.WriteLine("Unknown option '{0}'", command);
Environment.Exit(1);
return;
}
}
} else {
AssemblyName = command;
}
}
if(args.Length == 0 || m_error != null) {
Usage ();
} else if(AssemblyName == null) {
Console.Error.WriteLine("No input file specified");
Environment.Exit(1);
}
}
/*
string GetCommand (string cmd, out string arg)
{
int sep = cmd.IndexOfAny (new char [] {':', '='}, 1);
if (sep == -1) {
arg = null;
return cmd.Substring (1);
}
string command = cmd.Substring (1, sep - 1);
arg = cmd.Substring (sep + 1);
return command.ToLower ();
}
*/
void Usage ()
{
Console.WriteLine (
"Mono CIL Disassembler");
if (m_error != null)
Console.WriteLine ("\n{0}\n", m_error);
Console.WriteLine (
"Usage: ildasm [<options>] <assembly>\n" +
" --about\t\t\tabout Mono CIL Disassembler\n" +
" --version\t\t\tprint version of the Mono CIL Disassembler\n" +
" --output <filename>\t\tprint disassembly into filename\n" +
" --no-alias don't use type name aliases\n");
Environment.Exit (255);
}
void Version ()
{
Console.WriteLine ("Mono CIL Disassembler version {0}",
Assembly.GetExecutingAssembly ().GetName ().Version.ToString ());
Environment.Exit (0);
}
void About ()
{
Console.WriteLine (
"Mono CIL Disassembler\n" +
"For more information on Mono, visit\n" +
" http://www.mono-project.com\n" +
"");
Environment.Exit (0);
}
}
}