155 lines
3.7 KiB
D
155 lines
3.7 KiB
D
/**
|
|
* Argument parsing.
|
|
*/
|
|
module elna.arguments;
|
|
|
|
import std.algorithm;
|
|
import std.range;
|
|
import std.sumtype;
|
|
|
|
struct ArgumentError
|
|
{
|
|
enum Type
|
|
{
|
|
expectedOutputFile,
|
|
noInput,
|
|
superfluousArguments,
|
|
}
|
|
|
|
private Type type_;
|
|
private string argument_;
|
|
|
|
@property Type type() const @nogc nothrow pure @safe
|
|
{
|
|
return this.type_;
|
|
}
|
|
|
|
@property string argument() const @nogc nothrow pure @safe
|
|
{
|
|
return this.argument_;
|
|
}
|
|
|
|
void toString(OR)(OR range)
|
|
if (isOutputRage!OR)
|
|
{
|
|
final switch (Type)
|
|
{
|
|
case Type.expectedOutputFile:
|
|
put(range, "Expected an output filename after -o");
|
|
break;
|
|
case Type.noInput:
|
|
put(range, "No input files specified");
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Supported compiler arguments.
|
|
*/
|
|
struct Arguments
|
|
{
|
|
private bool assembler_;
|
|
private string output_;
|
|
private string inFile_;
|
|
|
|
@property string inFile() @nogc nothrow pure @safe
|
|
{
|
|
return this.inFile_;
|
|
}
|
|
|
|
/**
|
|
* Returns: Whether to generate assembly instead of an object file.
|
|
*/
|
|
@property bool assembler() const @nogc nothrow pure @safe
|
|
{
|
|
return this.assembler_;
|
|
}
|
|
|
|
/**
|
|
* Returns: Output file.
|
|
*/
|
|
@property string output() const @nogc nothrow pure @safe
|
|
{
|
|
return this.output_;
|
|
}
|
|
|
|
/**
|
|
* Parse command line arguments.
|
|
*
|
|
* The first argument is expected to be the program name (and it is
|
|
* ignored).
|
|
*
|
|
* Params:
|
|
* arguments = Command line arguments.
|
|
*
|
|
* Returns: Parsed arguments or an error.
|
|
*/
|
|
static SumType!(ArgumentError, Arguments) parse(string[] arguments)
|
|
@nogc nothrow pure @safe
|
|
{
|
|
if (!arguments.empty)
|
|
{
|
|
arguments.popFront;
|
|
}
|
|
alias ReturnType = typeof(return);
|
|
|
|
return parseArguments(arguments).match!(
|
|
(Arguments parsed) {
|
|
if (parsed.inFile is null)
|
|
{
|
|
return ReturnType(ArgumentError(ArgumentError.Type.noInput));
|
|
}
|
|
else if (!arguments.empty)
|
|
{
|
|
return ReturnType(ArgumentError(
|
|
ArgumentError.Type.superfluousArguments,
|
|
arguments.front
|
|
));
|
|
}
|
|
return ReturnType(parsed);
|
|
},
|
|
(ArgumentError argumentError) => ReturnType(argumentError)
|
|
);
|
|
}
|
|
|
|
private static SumType!(ArgumentError, Arguments) parseArguments(ref string[] arguments)
|
|
@nogc nothrow pure @safe
|
|
{
|
|
Arguments parsed;
|
|
|
|
while (!arguments.empty)
|
|
{
|
|
if (arguments.front == "-s")
|
|
{
|
|
parsed.assembler_ = true;
|
|
}
|
|
else if (arguments.front == "-o")
|
|
{
|
|
if (arguments.empty)
|
|
{
|
|
return typeof(return)(ArgumentError(
|
|
ArgumentError.Type.expectedOutputFile,
|
|
arguments.front
|
|
));
|
|
}
|
|
arguments.popFront;
|
|
parsed.output_ = arguments.front;
|
|
}
|
|
else if (arguments.front == "--")
|
|
{
|
|
arguments.popFront;
|
|
parsed.inFile_ = arguments.front;
|
|
arguments.popFront;
|
|
break;
|
|
}
|
|
else if (!arguments.front.startsWith("-"))
|
|
{
|
|
parsed.inFile_ = arguments.front;
|
|
}
|
|
arguments.popFront;
|
|
}
|
|
return typeof(return)(parsed);
|
|
}
|
|
}
|