// Copyright (c) 2012-2023 Wojciech Figat. All rights reserved.
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Reflection;
namespace Flax.Build
{
///
/// The command line utilities.
///
public class CommandLine
{
internal static List ConsoleCommands;
///
/// The command line option data.
///
public class Option
{
///
/// The name.
///
public string Name;
///
/// The value.
///
public string Value;
///
public override string ToString()
{
if (string.IsNullOrEmpty(Value))
return $"/{Name}";
return $"/{Name}={Value}";
}
}
///
/// Gets the program executable string. Post-processed to improve parsing performance.
///
/// The command line.
public static string Get()
{
string[] args = Environment.GetCommandLineArgs();
if (args.Length > 1)
{
string commandLine = Environment.CommandLine.Remove(0, args[0].Length + 2);
commandLine = commandLine.Trim(' ');
return commandLine;
}
return string.Empty;
}
///
/// Gets the help information for the command line options for the given type.
///
/// The type.
/// The options help information.
public static string GetHelp(Type type)
{
StringWriter result = new StringWriter();
result.WriteLine("Usage: Flax.Build.exe [options]");
result.WriteLine("Options:");
var options = GetMembers(type);
foreach (var option in options)
{
result.Write(" -" + option.Key.Name);
if (!string.IsNullOrEmpty(option.Key.ValueHint))
{
result.Write("={0}", option.Key.ValueHint);
}
result.WriteLine();
if (!string.IsNullOrEmpty(option.Key.Description))
{
result.WriteLine("\t{0}", option.Key.Description.Replace(Environment.NewLine, Environment.NewLine + "\t"));
}
result.WriteLine();
}
return result.ToString();
}
///
/// Gets the options for command line configuration for the given type.
///
/// The type.
/// The list of configurable options.
public static Dictionary GetMembers(Type type)
{
if (type == null)
throw new ArgumentNullException();
var result = new Dictionary();
var members = type.GetMembers(BindingFlags.Static | BindingFlags.Public);
for (int i = 0; i < members.Length; i++)
{
var member = members[i];
var attribute = member.GetCustomAttribute();
if (attribute != null)
{
result.Add(attribute, member);
}
}
return result;
}
///
/// Gets the options for command line configuration for the given object instance.
///
/// The object instance.
/// The list of configurable options.
public static Dictionary GetMembers(object obj)
{
if (obj == null)
throw new ArgumentNullException();
var result = new Dictionary();
var type = obj.GetType();
var members = type.GetMembers(BindingFlags.Instance | BindingFlags.Public);
for (int i = 0; i < members.Length; i++)
{
var member = members[i];
var attribute = member.GetCustomAttribute();
if (attribute != null)
{
result.Add(attribute, member);
}
}
return result;
}
private static int _cacheHash;
private static readonly object _cacheLock = new object();
private static Option[] _cacheOptions;
///
/// Determines whether the specified option has been specified in the environment command line.
///
/// The option name.
/// true if the specified option has been specified; otherwise, false.
public static bool HasOption(string name)
{
return HasOption(name, Get());
}
///
/// Determines whether the specified option has been specified in the environment command line.
///
/// The option name.
/// The command line.
/// true if the specified option has been specified; otherwise, false.
private static bool HasOption(string name, string commandLine)
{
return commandLine.Length > 0 && GetOptions(commandLine).Any(p => (string.Equals(p.Name, name, StringComparison.OrdinalIgnoreCase)));
}
///
/// Gets the options for the current environment command line.
///
/// The options.
public static Option[] GetOptions()
{
return GetOptions(Get());
}
///
/// Gets the options for the given command line.
///
/// The command line.
/// The options.
public static Option[] GetOptions(string commandLine)
{
int hash = commandLine.GetHashCode();
Option[] options;
lock (_cacheLock)
{
if (hash != _cacheHash)
{
_cacheHash = hash;
_cacheOptions = Parse(commandLine);
}
options = _cacheOptions;
}
return options;
}
///
/// Gets the options for the given configuration (key=value pairs).
///
/// The configuration (key=value pairs).
/// The options.
public static Option[] GetOptions(Dictionary configuration)
{
var options = new Option[configuration.Count];
int i = 0;
foreach (var e in configuration)
{
options[i++] = new Option
{
Name = e.Key,
Value = e.Value,
};
}
return options;
}
///
/// Parses the specified command line.
///
/// The command line.
/// The options.
public static Option[] Parse(string commandLine)
{
var options = new List