-
-
Notifications
You must be signed in to change notification settings - Fork 1
Home
Parsing command-line arguments is a critical portion of most applications.
From overriding default values to completely modifiying the application's behaviour, command-line arguments are a powerful tool.
getopt.net supports both the POSIX-like implementation and also the GNU-extensions for getopt.
One of the many GNU extensions to getopt, is allowing an option argument to be added alongside a short opt.
This means that instead of requiring a space between for example -c someval
, it is completely legal to also write -csomevalx
.
var getopt = new GetOpt {
ShortOpts = "c:",
AppArgs = new[] { "-c" "someval", "-csomevalx" }
};
var optChar = 0;
while ((optChar = getopt.GetNextOpt(out var optArg)) != -1) {
Console.WriteLine($"Got option '{ (char)optChar }' with option \"{ optArg }\"")
}
// Output:
// => Got option 'c' with option "someval"
// => Got option 'c' with option "somvalx"
If ShortOpts
is prefixed with a +
or the environment variable POSIXLY_CORRECT
is set, getopt.net will stop parsing options as soon as the first non-option argument is encountered.
Example:
var getopt = new GetOpt {
ShortOpts = "+ab:cd:ef",
AppArgs = new[] { "-b", "somevalue" }
};
// as soon as "somevalue" is encountered, getopt.net will cease parsing options
// instead, GetNextOpt will return (char)1 and outOptArg will be set to the encountered values
var optChar;
while ((getopt.GetNextOpt(out var optArg)) != -1) {
if (optChar != 1) {
Console.WriteLine($"Found argument '{ optChar }' with optArg { (optArg ?? "\"no argument\"") }");
} else {
Console.WriteLine($"Option parsing has stopped. Got argument: { optArg }");
}
}
// Output:
// => Found argument 'b' with OptArg "no argument"
// => Option parsing has stopped. Got argument: somvalue
If ShortOpts
is prefixed with a '-', then each non-option value which isn't the argument of an option is treated as though it were the argument for an option with the value of (char)1
.
This is useful for parsing filenames for example.
Example:
var getopt = new GetOpt {
ShortOpts = "hvc:", // only the 'c' option requires an argument
AppArgs = new[] { "-cvalue", "filename.txt" "-hv", "filename2.txt" }
};
var optChar = 0;
while ((optChar = getopt.GetNextOpt(out var optArg)) != -1) {
switch (optChar) {
case 1:
Console.WriteLine($"Got non-option value \"{ optArg }\"");
break;
default:
Console.WriteLine($"Got option '{ (char)optChar }' with argument \"{ (optArg ?? "no optarg") }\"");
break;
}
}
// Output:
// => Got option 'c' with argument "value"
// => Got non-option value "filename.txt"
// => Got option 'h' with argument "no optarg"
// => Got option 'v' with argument "no optarg"
// => Got non-option value "filename2.txt"
As of v0.3.x getopt.net does not support treating short options as long options.
In getopt, this is accomplished by suffing the short opt with a Semicolon.
If demand is high enough or someone is willing to implement this functionality, then it will be merged into the master branch.
Example:
var getopt = new GetOpt {
ShortOpts = "a:b;cfg", // inserting "b;" results in undefined behaviour!
};
As of v0.3.x getopt.net does not support optional arguments for short options.
This is likely to change in future!
In getopt, adding optional arguments to short opts is done by suffxing each legal argument with a double-colon.
Example:
var getopt = new GetOpt {
ShortOpts = "ab:c::", // inserting "c::" results in indefined behaviour!
};
getopt.net supports short options requiring arguments.
The behaviour of getopt.net will depend on the options you have set!
var getopt = new GetOpt {
ShortOpts = "ab:cd:",
IgnoreMissingArgument = true // GetNextOpt will return MissingOptChar if an argument is missing
AppArgs = new[] { "-abtest", "-cd" }
};
var optChar = 0;
while ((optChar = getopt.GetNextOpt(out var optArg)) != -1) {
switch (optChar) {
case getopt.MissingOptChar:
Console.WriteLine("Encountered option with missing argument!");
break; // in this mode, there is currently no mechanism to get the supplied option
default:
Console.WriteLine($"Got option '{ (char)optChar }' with argument \"{ (optArg ?? "null argument") }\"");
break;
}
}
// Output:
// => Got option 'a' with argument "null argument"
// => Got option 'b' with argument "test"
// => Got option 'c' with argument "null argument"
// => Encountered option with missing argument!
var getopt = new GetOpt {
ShortOpts = "ab:cd:",
IgnoreMissingArgument = false, // GetNextOpt will throw a ParseException if an argument is missing
AppArgs = new[] { "-abtest", "-cd" }
};
var optChar = 0;
do {
string? optArg;
try { optChar = getopt.GetNextOpt(out optArg); }
catch (ParseException ex) {
Console.WriteLine(ex.ToString());
continue;
}
switch (optChar) {
case -1: break;
default:
Console.WriteLine($"Got option '{ optChar }' with argument \"{ (optArg ?? "null argument") }\"");
}
} while (optChar != -1);
// Output:
// => Got option 'a' with argument "null argument"
// => Got option 'b' with argument "test"
// => Got option 'c' with argument "null argument"
// => Error occurred while parsing 'd': Missing required argument
getopt.net supports with short and long options.
Short options are prefixed with a single dash (-), wheras long options are prefixed with a double-dash (--).
By default, getopt.net allows parsing both short options and long options.
The default behaviour is equivalent to calling getopt_long()
.
Unlike getopt_long()
, the last element of Options
must not be all zeros.
This behaviour can be modified, by setting getopt.ShortOptsOnly
, which is now equivalent to calling getopt()
.
Not setting the ShortOpts
property is equivalent to calling getopt_long_only()
.
var getopt = new GetOpt {
Options = new[] {
new Option { Name = "aoption", ArgumentType = ArgumentType.None, Value = 'a' },
new Option { Name = "boption", ArgumentType = ArgumentType.Required, Value = 'b' },
new Option { Name = "coption", ArgumentType = ArgumentType.Optional, Value = 'c' }
},
AppArgs = new[] { "--aoption", "--boption=test", "--coption", "test2", "somerandomvalue" }
};
var optChar = 0;
while ((optChar = getopt.GetNextOpt(out var optArg)) != -1) {
switch (optChar) {
case 'a':
Console.WriteLine("Got --aoption");
break;
case 'b':
Console.WriteLine($"Got --boption with argument \"{ optArg }\"");
break;
case 'c':
if (string.IsNullOrEmpty(optArg)) {
Console.WriteLine("Got --coption without argument.");
} else {
Console.WriteLine($"Got --coption with argument \"{ optArg }\"");
}
break;
case '?': // equivalent to case GetOpt.MissingArgChar:
Console.WriteLine("Got argument with missing char!");
break;
case 1:
Console.WriteLine($"Got non-option arg \"{ optArg }\"");
break;
}
}
// Output:
// => Got --aoption
// => Got --boption with argument "test"
// => Got --coption with argument "test2"
// => Got non-option arg "somerandomvalue"
If you've forgotten to add one of your Options
to your ShortOpts
, getopt.net has you covered!
If getopt.net encounteres a short option that isn't found in ShortOpts
, it will double-check in Options
to see if the option can be found there. It will the be parsed with with the options set there.
var getopt = new GetOpt {
ShortOpts = "ab:c",
Options = new[] {
new Option("aoption", ArgumentType.None, 'a'),
new Option("boption", ArgumentType.Required, 'b'),
new Option("coption", ArgumentType.Optional, 'c'),
new Option("doption", ArgumentType.None, 'd') // this was not added to ShortOpts
},
AppArgs = new[] { "-dacbtest" }
};
var optChar = 0;
while ((optChar = getopt.GetNextOpt(out var optArg)) != -1) {
Console.Write($"Got option '{ (char)optChar }' ");
if (string.IsNullOrEmpty(optArg)) {
Console.WriteLine("without optarg.");
} else {
Console.WriteLine($"with optarg \"{ optArg }\".");
}
}
// Output:
// => Got option 'd' without optarg.
// => Got option 'a' without optarg.
// => Got option 'c' without optarg.
// => Got option 'b' with optarg "test".
Written with ❤️ by Simon Cahill.
Have you contributed to this wiki? Don't forget to add your name(s) up above!
Can't find a solution to your problem? Create an Issue Want to share your cool developments/improvements with the rest of us? Create a Pull Request
If no icons are shown, please reload the page.
All icons procured from https://www.iconfinder.com/iconsets/essentials-pack