问题
I'm trying to get options parsing using OptionContext
to work.
My code so far:
public class Options : GLib.Object {
public string option_output = "";
public Options () {
}
public void parse (string args[]) throws OptionError {
// string option_output;
const OptionEntry[] options = {
{ "output", 'o', 0, OptionArg.FILENAME,
ref option_output, "file name for encoded output (required);",
"FILE" },
{null}
};
var opt_context = new OptionContext ("- vpng2theora");
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
unowned string[] temp_args = args;
foreach (var arg in temp_args) {
print ("arg: %s\n", arg);
}
opt_context.parse (ref temp_args);
print (option_output);
}
}
int main (string[] args) {
Options opts = new Options ();
opts.parse (args);
return 0;
}
As it stands this doesn't compile because:
error: Value must be constant
If I remove the const
altogether:
OptionEntry[] options = {
{ "output", 'o', 0, OptionArg.FILENAME,
ref option_output, "file name for encoded output (required);",
"FILE" },
{null}
};
The error is:
error: Expected array element, got array initializer list
The only way I can get around this problem is declaring the option_output
as a static
class field, but that defeats the purpose of instantiation.
Is there any way to have the OptionContext parsing work on an instance instead of a static class?
回答1:
The following will work:
public class Options : GLib.Object {
public string option_output = "";
public bool parse (ref unowned string[] args) {
var options = new OptionEntry[2];
options[0] = { "output", 'o', 0, OptionArg.FILENAME,
ref option_output, "file name for encoded output (required);",
"FILE" };
options[1] = {null};
var opt_context = new OptionContext ("- vpng2theora");
opt_context.set_help_enabled (true);
opt_context.add_main_entries (options, null);
foreach (var arg in args) {
print ("arg: %s\n", arg);
}
bool result= true;
try {
opt_context.parse (ref args);
print( option_output );
} catch {
result = false;
}
return result;
}
}
int main (string[] args) {
Options opts = new Options ();
if (!opts.parse (ref args)) { return -1; }
return 0;
}
The options parsing will remove the optional arguments and then you can parse the required ones, such as the filenames to process. That's why I've kept the original args
passed to the parse function. So you will get a cleaned set of args
back, that you can then parse again for the required arguments. I found "CLI design: Putting flags to good use" a useful read.
options
is an array of structs. I don't understand well enough why setting the size of the array is necessary, but it works for me.
来源:https://stackoverflow.com/questions/33431446/how-to-do-optioncontext-parsing-on-an-instance