Command Line Subcommands in UnrealScript

Here’s the translation of the Go code to UnrealScript, along with explanations in Markdown format suitable for Hugo:

class CommandLineSubcommands extends Object;

struct FlagSet
{
    var string Name;
    var array<string> Args;
};

var FlagSet FooCmd, BarCmd;
var bool bFooEnable;
var string FooName;
var int BarLevel;

function Init()
{
    // We declare subcommands using FlagSet structs, and proceed to define
    // new flags specific for each subcommand.
    FooCmd.Name = "foo";
    BarCmd.Name = "bar";
}

function ParseArguments(array<string> Args)
{
    local int i;
    local string Arg, Value;
    local FlagSet CurrentCmd;

    if (Args.Length < 2)
    {
        `Log("expected 'foo' or 'bar' subcommands");
        return;
    }

    // Check which subcommand is invoked.
    switch (Args[1])
    {
        case "foo":
            CurrentCmd = FooCmd;
            break;
        case "bar":
            CurrentCmd = BarCmd;
            break;
        default:
            `Log("expected 'foo' or 'bar' subcommands");
            return;
    }

    // For every subcommand, we parse its own flags and
    // have access to trailing positional arguments.
    for (i = 2; i < Args.Length; i++)
    {
        Arg = Args[i];
        if (Left(Arg, 1) == "-")
        {
            if (InStr(Arg, "=") != -1)
            {
                ParseKeyValueArg(CurrentCmd, Arg);
            }
            else
            {
                ParseFlagArg(CurrentCmd, Arg);
            }
        }
        else
        {
            CurrentCmd.Args.AddItem(Arg);
        }
    }

    // Output the parsed arguments
    OutputParsedArguments(CurrentCmd);
}

function ParseKeyValueArg(out FlagSet Cmd, string Arg)
{
    local array<string> KeyValue;
    ParseStringIntoArray(Arg, KeyValue, "=", true);
    
    if (KeyValue.Length == 2)
    {
        switch (Cmd.Name)
        {
            case "foo":
                if (KeyValue[0] == "-name")
                {
                    FooName = KeyValue[1];
                }
                break;
            case "bar":
                if (KeyValue[0] == "-level")
                {
                    BarLevel = int(KeyValue[1]);
                }
                break;
        }
    }
}

function ParseFlagArg(out FlagSet Cmd, string Arg)
{
    if (Cmd.Name == "foo" && Arg == "-enable")
    {
        bFooEnable = true;
    }
}

function OutputParsedArguments(FlagSet Cmd)
{
    local int i;

    `Log("subcommand '"$Cmd.Name$"'");
    
    switch (Cmd.Name)
    {
        case "foo":
            `Log("  enable:" @ bFooEnable);
            `Log("  name:" @ FooName);
            break;
        case "bar":
            `Log("  level:" @ BarLevel);
            break;
    }

    `Log("  tail:");
    for (i = 0; i < Cmd.Args.Length; i++)
    {
        `Log("    " $ Cmd.Args[i]);
    }
}

This UnrealScript code demonstrates how to implement command-line subcommands similar to the Go example. However, UnrealScript doesn’t have built-in support for command-line argument parsing like Go’s flag package. Instead, we’ve implemented a basic argument parsing system using UnrealScript’s language features.

Here’s how it works:

  1. We define a FlagSet struct to represent subcommands and their arguments.

  2. The Init function sets up the subcommands “foo” and “bar”.

  3. The ParseArguments function takes an array of strings (simulating command-line arguments) and parses them based on the subcommand.

  4. ParseKeyValueArg and ParseFlagArg handle different types of arguments (key-value pairs and flags).

  5. OutputParsedArguments displays the parsed arguments, similar to the Go example.

To use this in UnrealScript, you would typically call these functions from an event or another function, passing in the arguments as an array of strings. For example:

function SomeEventOrFunction()
{
    local array<string> Args;
    
    Init();
    
    // Simulate command-line arguments
    Args.AddItem("program");
    Args.AddItem("foo");
    Args.AddItem("-enable");
    Args.AddItem("-name=joe");
    Args.AddItem("a1");
    Args.AddItem("a2");
    
    ParseArguments(Args);
}

This would produce output similar to the Go example:

subcommand 'foo'
  enable: True
  name: joe
  tail:
    a1
    a2

Note that UnrealScript doesn’t have a direct equivalent to Go’s command-line execution environment. This implementation simulates that behavior within the context of Unreal Engine’s scripting system.