diff --git a/ProtectionScan/Options.cs b/ProtectionScan/Options.cs
deleted file mode 100644
index 1e6901e9..00000000
--- a/ProtectionScan/Options.cs
+++ /dev/null
@@ -1,127 +0,0 @@
-using System;
-using System.Collections.Generic;
-
-namespace ProtectionScan
-{
- ///
- /// Set of options for the test executable
- ///
- internal sealed class Options
- {
- #region Properties
-
- ///
- /// Enable debug output for relevant operations
- ///
- public bool Debug { get; private set; } = false;
-
- ///
- /// Set of input paths to use for operations
- ///
- public List InputPaths { get; private set; } = [];
-
- ///
- /// Scan archives during protection scanning
- ///
- public bool ScanArchives { get; private set; } = true;
-
- ///
- /// Scan file contents during protection scanning
- ///
- public bool ScanContents { get; private set; } = true;
-
- ///
- /// Scan file paths during protection scanning
- ///
- public bool ScanPaths { get; private set; } = true;
-
- ///
- /// Scan subdirectories during protection scanning
- ///
- public bool ScanSubdirectories { get; set; } = true;
-
- #endregion
-
- ///
- /// Parse commandline arguments into an Options object
- ///
- public static Options? ParseOptions(string[] args)
- {
- // If we have invalid arguments
- if (args == null || args.Length == 0)
- return null;
-
- // Create an Options object
- var options = new Options();
-
- // Parse the options and paths
- for (int index = 0; index < args.Length; index++)
- {
- string arg = args[index];
- switch (arg)
- {
- case "-?":
- case "-h":
- case "--help":
- return null;
-
- case "-d":
- case "--debug":
- options.Debug = true;
- break;
-
- case "-na":
- case "--no-archives":
- options.ScanArchives = false;
- break;
-
- case "-nc":
- case "--no-contents":
- options.ScanContents = false;
- break;
-
- case "-np":
- case "--no-paths":
- options.ScanPaths = false;
- break;
-
- case "-ns":
- case "--no-subdirs":
- options.ScanSubdirectories = false;
- break;
-
- default:
- options.InputPaths.Add(arg);
- break;
- }
- }
-
- // Validate we have any input paths to work on
- if (options.InputPaths.Count == 0)
- {
- Console.WriteLine("At least one path is required!");
- return null;
- }
-
- return options;
- }
-
- ///
- /// Display a basic help text
- ///
- public static void DisplayHelp()
- {
- Console.WriteLine("Protection Scanner");
- Console.WriteLine();
- Console.WriteLine("ProtectionScan ...");
- Console.WriteLine();
- Console.WriteLine("Options:");
- Console.WriteLine("-?, -h, --help Display this help text and quit");
- Console.WriteLine("-d, --debug Enable debug mode");
- Console.WriteLine("-nc, --no-contents Disable scanning for content checks");
- Console.WriteLine("-na, --no-archives Disable scanning archives");
- Console.WriteLine("-np, --no-paths Disable scanning for path checks");
- Console.WriteLine("-ns, --no-subdirs Disable scanning subdirectories");
- }
- }
-}
diff --git a/ProtectionScan/Program.cs b/ProtectionScan/Program.cs
index 7411c485..752fa139 100644
--- a/ProtectionScan/Program.cs
+++ b/ProtectionScan/Program.cs
@@ -2,11 +2,24 @@
using System.Collections.Generic;
using System.IO;
using BinaryObjectScanner;
+using SabreTools.CommandLine;
+using SabreTools.CommandLine.Inputs;
namespace ProtectionScan
{
class Program
{
+ #region Constants
+
+ private const string _debugName = "debug";
+ private const string _helpName = "help";
+ private const string _noArchivesName = "no-archives";
+ private const string _noContentsName = "no-contents";
+ private const string _noPathsName = "no-paths";
+ private const string _noSubdirsName = "no-subdirs";
+
+ #endregion
+
static void Main(string[] args)
{
#if NET462_OR_GREATER || NETCOREAPP || NETSTANDARD2_0_OR_GREATER
@@ -18,32 +31,77 @@ namespace ProtectionScan
var fileProgress = new Progress();
fileProgress.ProgressChanged += Changed;
- // Get the options from the arguments
- var options = Options.ParseOptions(args);
+ // Create the command set
+ var commandSet = CreateCommands();
- // If we have an invalid state
- if (options == null)
+ // If we have no args, show the help and quit
+ if (args == null || args.Length == 0)
{
- Options.DisplayHelp();
+ commandSet.OutputAllHelp();
+ return;
+ }
+
+ // Loop through and process the options
+ int firstFileIndex = 0;
+ for (; firstFileIndex < args.Length; firstFileIndex++)
+ {
+ string arg = args[firstFileIndex];
+
+ var input = commandSet.GetTopLevel(arg);
+ if (input == null)
+ break;
+
+ input.ProcessInput(args, ref firstFileIndex);
+ }
+
+ // If help was specified
+ if (commandSet.GetBoolean(_helpName))
+ {
+ commandSet.OutputAllHelp();
return;
}
// Create scanner for all paths
var scanner = new Scanner(
- options.ScanArchives,
- options.ScanContents,
- options.ScanPaths,
- options.ScanSubdirectories,
- options.Debug,
+ !commandSet.GetBoolean(_noArchivesName),
+ !commandSet.GetBoolean(_noContentsName),
+ !commandSet.GetBoolean(_noPathsName),
+ !commandSet.GetBoolean(_noSubdirsName),
+ !commandSet.GetBoolean(_debugName),
fileProgress);
// Loop through the input paths
- foreach (string inputPath in options.InputPaths)
+ for (int i = firstFileIndex; i < args.Length; i++)
{
- GetAndWriteProtections(scanner, inputPath);
+ string arg = args[i];
+ GetAndWriteProtections(scanner, arg);
}
}
+ ///
+ /// Create the command set for the program
+ ///
+ private static CommandSet CreateCommands()
+ {
+ List header = [
+ "Protection Scanner",
+ string.Empty,
+ "ProtectionScan file|directory ...",
+ string.Empty,
+ ];
+
+ var commandSet = new CommandSet(header);
+
+ commandSet.Add(new FlagInput(_helpName, ["-?", "-h", "--help"], "Display this help text"));
+ commandSet.Add(new FlagInput(_debugName, ["-d", "--debug"], "Enable debug mode"));
+ commandSet.Add(new FlagInput(_noContentsName, ["-nc", "--no-contents"], "Disable scanning for content checks"));
+ commandSet.Add(new FlagInput(_noArchivesName, ["-na", "--no-archives"], "Disable scanning archives"));
+ commandSet.Add(new FlagInput(_noPathsName, ["-np", "--no-paths"], "Disable scanning for path checks"));
+ commandSet.Add(new FlagInput(_noSubdirsName, ["-ns", "--no-subdirs"], "Disable scanning subdirectories"));
+
+ return commandSet;
+ }
+
///
/// Wrapper to get and log protections for a single path
///
diff --git a/ProtectionScan/ProtectionScan.csproj b/ProtectionScan/ProtectionScan.csproj
index 62ca3590..39e4509c 100644
--- a/ProtectionScan/ProtectionScan.csproj
+++ b/ProtectionScan/ProtectionScan.csproj
@@ -32,6 +32,7 @@
+