Next: , Previous: APIs, Up: APIs


7.1 Option Parsing

The option parsing classes can be used to extract values from strings such as yags:tag_size=5:style=fancy:war=peace:x=spot and are to be used for parsing user option strings from RTIs and other places. It is easy to provide default values, and checks are automatically made for duplicated or unrecognized arguments.

To use the class instantiate an object with the string to be parsed and an optional default specification as arguments. Consider:

       Option_AV opt(summarize_insn,"branch_misp=10:jump_misp=5");
     
       int bm_lines = opt.get_int("branch_misp");
       int accuracy_threshold = opt.get_double("accuracy_min");
     

In the example above summarize_insn points to the string to be parsed and the default specification indicates two default values, 10 for attribute branch_misp and 5 for jump_misp. The next two lines in the example read the values found in summarize_insn, substituting the defaults if necessary. No default was specified for accuracy_min, and so execution will exit with a run-time fatal error if summarize_insn does not have a value for accuracy_min. Execution will also end with an error if summarize_insn contains an attribute with no corresponding value in the default specification or in a call like get_int.

— Class: Option_AV char* option_string char* option_defaults
— Class: Option_NAV char* option_string char* option_defaults

Parse option_string which is expected to be a sequence of attributes and values, substituting values specified in option_defaults if necessary. Check for unexpected duplicate attributes. If any attributes in option_string are not referenced by the time the object is destructed execution will end with a fatal error unless check_unused is called.

The format of option_string for Option_NAV is NAME: ATTR1=VAL1: ATTR2=VAL2: ..., with the = optional.

If = is omitted then either ATTR is assumed to be one character or VAL is assumed to be zero characters, the former assumption is made iff option_defaults is present and all attributes are one character. The one-character attribute assumption allows a compact option string, `"t5:n22:rbooks"' instead of `"t=5:n=22:r=books"'. The zero-character value assumption allows the option string to specify attributes without values. For example, `"red:blue:green"' instead of `"red=1:blue=1:green=1"'.

The format of option_defaults is the same except that a value of *, rather than indicating a default, indicates that the attribute can have any number of values. For example, for default x=12:array=*, the following option string is valid despite array appearing twice array=10:array=6:x=100.

The attribute names can't contain a : or =. They can contain a , but that's not a good idea. Be conservative with characters, some characters might become special in the future.

In the example below the object is being used to extract arguments for the yags branch predictor from the bp_method RTI.

            Option_NAV args(bp_method,"tag_size=4:weight=1.2");
            const int tag_size = args.get_int("tag_size");
            const double weight = args.get_double("weight");
     
— Function: char* Option_AV::get_str char* attr
— Function: int Option_AV::get_int char* attr
— Function: double Option_AV::get_double char* attr

Return value corresponding to attr. If attr does not appear in option_string or in option_defaults then get_int and get_double will raise a fatal error while get_str will just return NULL. The string returned by get_str will be freed when Option_AV is destructed.

There is no check that the value specified looks like the requested type: For get_int the value is converted by atoi and for get_double the value is converted by atof, regardless of what the values look like. If a * was specified for the default the return from get_str will be the concatenation of the values separated by :. Use PSplit to separate them.

            #include "oparse.h"
            Option_AV args(ez_profile_diff_arg,"r*:wlast_run:n15:t0.5:m10");
            ezd->examine_exe_count_min = args.get_int("m");
            ezd->examine_percentile = args.get_double("t");
            PSplit read_names(args.get_str("r"),':',0,PSplit::DontFree);
            while( read_names ) ezd->read_names += read_names;
          
            // Value for annotate_insns might be: "loads", "loads:branches", or "branches".
            Option_AV opt(annotate_insns);
            opt_per_branch = opt.get_str("branches"); // Return NULL if not present ...
            opt_per_load = opt.get_str("loads");      // or "" if present.
          
     
— Function: bool Option_AV::present char* attr

Return true if attr present in option_string or option_defaults, otherwise return false.

— Function: char* Option_AV::check_unused

Return a string showing all of those attributes in option_string which have so far not been used. The attributes are returned as a single string with : separating them, a NULL is returned if all attributes have been used. The returned string will remain for a while, don't free it.

If this function is not called and there are unused attributes then when the object is destructed execution will end with a fatal error.

Use this function to provide your own error message or to ignore unused attributes. To avoid frustrating users, don't ignore unused attributes unless some other code checks for them.

            Option_NAV args(bp_method,"tag_size=4:weight=1.2");
            const int tag_size = args.get_int("tag_size");
            if( char *problem_attr = args.check_unused() )
             printf("Problems with attributes %s\n",problem_attr);