How to do OptionContext parsing on an instance?

Deadly 提交于 2019-12-13 01:05:31

问题


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

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!