singrdk/base/Windows/mlarm/mlarm.cs

276 lines
10 KiB
C#
Raw Permalink Normal View History

2008-11-17 18:29:00 -05:00
///////////////////////////////////////////////////////////////////////////////
//
// Microsoft Research Singularity
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
// File: mlarm.cs
//
// Note: Parse ML style arguments and invoked ARMASM.
//
using System;
using System.Collections;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.IO;
using System.Text;
namespace Microsoft.Singularity.Applications
{
public class ArmAsmWrapper
{
// Print the correct command line args for the program
static void Usage()
{
Console.WriteLine(
"Usage:\n"+
" MLARM [ /options ] filelist [ /link linkoptions ]\n"+
"\n"+
"Options:\n"+
" /c Assemble without linking\n"+
" /Cp Preserve case of user identifiers [ignored]\n"+
" /Cx Preserve case in publics, externs [ignored]\n"+
" /D<name>[=text] Define text macro\n"+
" /Fl[file] Generate listing\n"+
" /Fo<file> Name object file\n"+
" /I<name> Add include path\n"+
" /nologo Suppress copyright message [ignored]\n"+
" /QRarch4 ARM4 Architecture\n"+
" /QRarch4T ARM4T Architecture\n"+
" /QRarch5 ARM5 Architecture\n"+
" /QRarch5T ARM5T Architecture\n"+
" /QRarch6 ARM6 Architecture\n"+
" /QRxscale XSCALE Architecture\n"+
" /Sa Maximize source listing\n"+
" /Sl<width> Set line width\n"+
" /Sp<length> Set page length\n"+
" /Sx List false conditionals\n"+
" /W<number> Set warning level\n"+
" /Zi Add symbolic debug info [ignored]\n"+
"\n"+
"Summary:\n"+
" Converts command arguments formats and calls armasm.");
}
static bool IsQuote(char c)
{
return (c == '"' || c == '\'');
}
static string RemoveQuotes(string text)
{
int start = 0;
int length = text.Length;
if (length > 0 && IsQuote(text[start + length - 1])) {
length--;
}
if (length > 0 && IsQuote(text[start])) {
start++;
length--;
}
if (start != 0 || length != text.Length) {
return text.Substring(start, length);
}
else {
return text;
}
}
static bool StringIsNullOrEmpty(string str)
{
return (str == null || str.Length == 0);
}
static bool ArgIsPrefix(string arg, string prefix)
{
return (arg == prefix);
}
static bool ArgIsPrefix(string arg, string prefix, string alt)
{
return (arg == prefix || arg == alt);
}
static string ArgHasPrefix(string arg, string prefix)
{
if (arg.StartsWith(prefix)) {
return arg.Substring(prefix.Length);
}
return null;
}
static string ArgHasPrefix(string arg, string prefix, string alt)
{
string ret = ArgHasPrefix(arg, prefix);
return (ret != null) ? ret : ArgHasPrefix(arg, alt);
}
static int Main(string[] args)
{
ArrayList outargs = new ArrayList();
// Temporaries for command-line parsing
bool needHelp = (args.Length == 0);
bool linkOnly = false;
bool nologo = false;
for (int i = 0; i < args.Length && !needHelp; i++) {
string arg = (string) args[i];
string val = null;
if (ArgIsPrefix(arg, "/c", "-c")) {
// Assemble without linking
linkOnly = true;
}
else if (ArgIsPrefix(arg, "/Cp", "-Cp")) {
// Preserve case of user identifiers.
}
else if (ArgIsPrefix(arg, "/Cx", "-Cx")) {
// Preserve case in publics, externs.
}
else if (ArgIsPrefix(arg, "/Cx", "-Cx")) {
}
else if ((val = ArgHasPrefix(arg, "/D", "-D")) != null) {
// <name>[=text] Define text macro
int index = val.IndexOf('=');
if (index > 0) {
outargs.Add(String.Format("-PreDefine \"{0} SETA {1}\"",
val.Substring(0, index),
val.Substring(index + 1)));
}
else {
outargs.Add(String.Format("-PreDefine \"{0} SETA {1}\"",
val, 1));
}
}
else if ((val = ArgHasPrefix(arg, "/Fl", "-Fl")) != null) {
// [file] Generate listing
outargs.Add("-list " + val);
}
else if ((val = ArgHasPrefix(arg, "/Fo", "-Fo")) != null) {
// <file> Name object file
outargs.Add("-o " + val);
}
else if ((val = ArgHasPrefix(arg, "/I", "-I")) != null) {
// <name> Add include path
outargs.Add("-I " + val);
}
else if (ArgIsPrefix(arg, "/nologo", "-nologo")) {
// Suppress copyright message
if (!nologo) {
outargs.Add("-nologo");
nologo = true;
}
}
else if (ArgIsPrefix(arg, "/QRarch4", "-QRarch4")) {
// ARM4 Architecture
outargs.Add("-ARCH 4");
}
else if (ArgIsPrefix(arg, "/QRarch4T", "-QRarch4T")) {
// ARM4T Architecture
outargs.Add("-ARCH 4T");
}
else if (ArgIsPrefix(arg, "/QRarch5", "-QRarch5")) {
// ARM5 Architecture
outargs.Add("-ARCH 5");
}
else if (ArgIsPrefix(arg, "/QRarch5T", "-QRarch5T")) {
// ARM5T Architecture
outargs.Add("-ARCH 5T");
}
else if (ArgIsPrefix(arg, "/QRarch6", "-QRarch6")) {
// ARM6 Architecture
outargs.Add("-ARCH 6");
}
else if (ArgIsPrefix(arg, "/QRxscale", "-QRxscale")) {
// XScale
outargs.Add("-CPU XSCALE");
}
else if (ArgIsPrefix(arg, "/Sa", "-Sa")) {
// Maximize source listing
}
else if ((val = ArgHasPrefix(arg, "/Sl", "-Sl")) != null) {
// <width> Set line width
outargs.Add("-Width " + val);
}
else if ((val = ArgHasPrefix(arg, "/Sp", "-Sp")) != null) {
// <length> Set page length
outargs.Add("-Length " + val);
}
else if (ArgIsPrefix(arg, "/Sx", "-Sx")) {
// <length> Set page length
outargs.Add("-NOTerse");
}
else if (ArgIsPrefix(arg, "/W0", "-W0")) {
// <number> Set warning level
outargs.Add("-NOWarn");
}
else if (ArgIsPrefix(arg, "/W1", "-W1")) {
// <number> Set warning level
}
else if (ArgIsPrefix(arg, "/W2", "-W2")) {
// <number> Set warning level
}
else if (ArgIsPrefix(arg, "/W3", "-W3")) {
// <number> Set warning level
}
else if (ArgIsPrefix(arg, "/Zi", "-Zi")) {
// Add symbolic debug info
}
else if (ArgIsPrefix(arg, "/?", "-?")) {
needHelp = true;
}
else if (ArgHasPrefix(arg, "/", "-") != null) {
Console.Error.WriteLine("mlarm: Invalid argument: {0}", arg);
break;
}
else {
outargs.Add(arg);
}
}
if (!linkOnly) {
Console.Error.WriteLine("mlarm: Missing without linking option (/c)");
needHelp = true;
}
if (needHelp) {
Usage();
return 1;
}
string arguments = null;
foreach (string s in outargs) {
if (arguments != null) {
arguments = arguments + " " + s;
}
else {
arguments = s;
}
}
Process p = new Process();
p.StartInfo.UseShellExecute = false;
p.StartInfo.RedirectStandardOutput = false;
p.StartInfo.FileName = "armasm.exe";
p.StartInfo.Arguments = arguments;
int exit = -1;
Console.WriteLine(" {0} {1}", p.StartInfo.FileName, p.StartInfo.Arguments);
try {
p.Start();
p.WaitForExit();
exit = p.ExitCode;
}
catch (Exception e) {
Console.WriteLine("mlarm: Exception: {0}", e);
}
return exit;
}
}
}