docs/cmdopts.mdwn
changeset 81 8e1ccd27d60f
parent 80 93088d0c8140
child 82 06d4a9185902
equal deleted inserted replaced
80:93088d0c8140 81:8e1ccd27d60f
    14  * Integrate and improve completion system.
    14  * Integrate and improve completion system.
    15  * Add common generic stuff, like '--help'.
    15  * Add common generic stuff, like '--help'.
    16  * Try to still be lightweight.
    16  * Try to still be lightweight.
    17  * Try to still be readable.
    17  * Try to still be readable.
    18 
    18 
    19 It is built around static structure, "command description". User can add or
    19 It is built around static structure, "command description".  User can add or
    20 remove these structures to list of commands. FIXME more
    20 remove these structures to list of commands.  *FIXME* more
    21 
    21 
    22 ## Command description struct, 'cmdopts_t'
    22 ## Command description struct, 'cmdopts_t'
    23 
    23 
    24 [[!format c """ // -------------------------------------------------------------
    24 [[!format c """// --------------------------------------------------------------
    25 
    25 
    26 typedef struct cmdopts_struct cmdopts_t;
    26 typedef struct cmdopts_struct cmdopts_t;
    27 
    27 
    28 typedef enum {
    28 typedef enum {
    29     cmd_default = 0x0000,
    29     cmd_default = 0x0000,
    40     const cmdopts_t     *cmds;
    40     const cmdopts_t     *cmds;
    41     const gpointer      userdata;
    41     const gpointer      userdata;
    42     size_t              valno;
    42     size_t              valno;
    43 };
    43 };
    44 
    44 
    45 // -------------------------------------------------------------      """     ]]
    45 // --------------------------------------------------------------     """     ]]
    46 
    46 
    47 This struct describes command as a whole and links to argument descriptions.
    47 This struct describes command as a whole and links to argument descriptions.
    48 This struct is also used to describe individual subcommands, as they are quite
    48 This struct is also used to describe individual subcommands, as they are quite
    49 similar to normal command, because they can have their own options, arguments
    49 similar to normal command, because they can have their own options, arguments
    50 and subcommands. The fields of this struct:
    50 and subcommands.  The fields of this struct:
    51 
    51 
    52  * 'name' - name of the command or subcommand.
    52  * 'name' - name of the command or subcommand.
    53 
    53 
    54  * 'flags' - currently there's only one flag:
    54  * 'flags' - currently there's only one flag:
    55 
    55 
    56     + 'cmd_safe' -  command is safe to execute in main mcabberrc during
    56     + 'cmd_safe' -  command is safe to execute in main mcabberrc during
    57       initialization. Have no meaning for subcommands.
    57       initialization.  Have no meaning for subcommands.
    58     + 'cmd_default' - default value of no flags enabled.
    58     + 'cmd_default' - default value of no flags enabled.
    59  
    59  
    60  * 'check' - execution environment checker for command. This callback is used to
    60  * 'check' - execution environment checker for command.  This callback is used
    61    do general checks before even parsing command line. You can write your own
    61    to do general checks before even parsing command line.  You can write your
    62    checker or use standard ones, for example - 'cmd_check_online', that checks,
    62    own checker or use standard ones, for example - 'cmd_check_online', that
    63    if you are currently online.
    63    checks, if you are currently online.
    64 
    64 
    65  * 'handle' - command function. It is executed only if command line was
    65  * 'handle' - command function.  It is executed only if command line was
    66    successfully parsed and argument values passed the type checking. Unused in
    66    successfully parsed and argument values passed the type checking.  Unused in
    67    subcommands.
    67    subcommands.
    68 
    68 
    69  * 'opts' - pointer to the array of 'cmdopt_t' structs, describing command-line
    69  * 'opts' - pointer to the array of 'cmdopt_t' structs, describing command-line
    70    options ("-f bar") and switches ("-x"), that this command accepts.
    70    options ("-f bar") and switches ("-x"), that this command accepts.  Array
       
    71    must end with option, that have 0 as short option character.
    71  
    72  
    72  * 'args' - similarly, pointer to the array of 'cmdarg_t' structs, that describe
    73  * 'args' - similarly, pointer to the array of 'cmdarg_t' structs, that describe
    73    command-line positional arguments (in order).
    74    command-line positional arguments (in order).  Array must end with argument,
       
    75    that have NULL name.
    74  
    76  
    75  * 'cmds' - pointer to the array of subcommands of this command (or subcommand).
    77  * 'cmds' - pointer to the array of subcommands of this command (or subcommand).
    76    How parser switches to subcommands we will describe later.
    78    How parser switches to subcommands we will describe later.  Array must end
       
    79    with subcommand, that have NULL name.
    77  
    80  
    78  * 'userdata' - arbitrary pointer, where you can put some data, that should
    81  * 'userdata' - arbitrary pointer, where you can put some data, that should
    79    accompany this command or subcommand. Unused by parser.
    82    accompany this command or subcommand.  Unused by parser.
    80 
    83 
    81  * 'valno' - this is internal value, that is initialized at command definition
    84  * 'valno' - this is internal value, that is initialized at command definition
    82    time, you should not modify it. Currently unused in subcommands.
    85    time, you should not modify it.  Currently unused in subcommands.
    83 
    86 
    84 ## Command function, 'cmd_handler_t'
    87 ## Command function, 'cmd_handler_t'
    85 
    88 
    86 [[!format c """ // -------------------------------------------------------------
    89 [[!format c """// --------------------------------------------------------------
    87 
    90 
    88 typedef gchar *(*cmd_handler_t) (cmdopts_t *command, cmdarg_value_t *values);
    91 typedef gchar *(*cmd_handler_t) (cmdopts_t *command, cmdarg_value_t *values);
    89 
    92 
    90 // -------------------------------------------------------------      """     ]]
    93 // --------------------------------------------------------------     """     ]]
    91 
    94 
    92 Command function is passed it's command definition struct (mainly to give it
    95 Command function is passed it's command definition struct (mainly to give it
    93 access to userdata) and dynamically allocated array of parsed argument values.
    96 access to userdata) and dynamically allocated array of parsed argument values.
    94 
    97 
    95 It should return NULL in case all went smoothly, or dynamically allocated error
    98 It should return NULL in case all went smoothly, or dynamically allocated error
    99 appear in command line and how to map all these options and arguments to array
   102 appear in command line and how to map all these options and arguments to array
   100 of values.
   103 of values.
   101 
   104 
   102 ## Option description struct, 'cmdopt_t'
   105 ## Option description struct, 'cmdopt_t'
   103 
   106 
   104 [[!format c """ // -------------------------------------------------------------
   107 [[!format c """// --------------------------------------------------------------
   105 
   108 
   106 typedef struct {
   109 typedef struct {
   107     const char stortopt;
   110     const char stortopt;
   108     const char *longopt;
   111     const char *longopt;
   109     cmdarg_t   arg;
   112     cmdarg_t   arg;
   110 } cmdopt_t;
   113 } cmdopt_t;
   111 
   114 
   112 // -------------------------------------------------------------      """     ]]
   115 // --------------------------------------------------------------     """     ]]
   113 
   116 
   114 This struct just adds short option character and long option name to generic
   117 This struct just adds short option character and long option name to generic
   115 argument struct, that we'll look at right now.
   118 argument struct, that we'll look at right now.
   116 
   119 
   117 ## Argument description struct, 'cmdarg_t'
   120 ## Argument description struct, 'cmdarg_t'
   118 
   121 
   119 [[!format c """ // -------------------------------------------------------------
   122 [[!format c """// --------------------------------------------------------------
   120 
   123 
   121 typedef struct cmdarg_struct cmdarg_t;
   124 typedef struct cmdarg_struct cmdarg_t;
   122 
   125 
   123 typedef enum {
   126 typedef enum {
   124     cmdarg_default  = 0x0000,
   127     cmdarg_default  = 0x0000,
   129     cmdarg_subcmd   = 0x0010,
   132     cmdarg_subcmd   = 0x0010,
   130     cmdarg_switch   = 0x0020,
   133     cmdarg_switch   = 0x0020,
   131     cmdarg_eol      = 0x0003, // catchall + plain
   134     cmdarg_eol      = 0x0003, // catchall + plain
   132     cmdarg_chreq    = 0x000C, // check + required
   135     cmdarg_chreq    = 0x000C, // check + required
   133     cmdarg_special  = 0x0030, // subcmd + switch
   136     cmdarg_special  = 0x0030, // subcmd + switch
       
   137     cmdarg_trigger  = 0x0024, // switch + check
   134 } cmdarg_flags_t;
   138 } cmdarg_flags_t;
   135 
   139 
   136 struct cmdarg_struct {
   140 struct cmdarg_struct {
   137     const char           *name;
   141     const char           *name;
   138     const guint          pos;
   142     const guint          pos;
   141     const cmdarg_type    *type;
   145     const cmdarg_type    *type;
   142     gconstpointer        chkdata;
   146     gconstpointer        chkdata;
   143     gconstpointer        userdata;
   147     gconstpointer        userdata;
   144 };
   148 };
   145 
   149 
   146 // -------------------------------------------------------------      """     ]]
   150 // --------------------------------------------------------------     """     ]]
   147 
   151 
   148 This struct stores information about mapping between command-line entity
   152 This struct stores information about mapping between command-line entity
   149 (switch, option, argument, subcommand) and element in 'values' array. First,
   153 (switch, option, argument, subcommand) and element in 'values' array.  First,
   150 let's briefly describe fields, and then walk through their use in different
   154 let's briefly describe fields, and then walk through their use in different
   151 entities.
   155 entities.
   152 
   156 
   153 Fields:
   157 Fields:
   154 
   158 
   176     + 'chreq' - shortcut for "argument must have a valid value".
   180     + 'chreq' - shortcut for "argument must have a valid value".
   177     + 'special' - this is special type of argument - subcommand or switch.
   181     + 'special' - this is special type of argument - subcommand or switch.
   178  
   182  
   179  * 'defval' - default value for argument in "unchecked" form - i.e., in the form
   183  * 'defval' - default value for argument in "unchecked" form - i.e., in the form
   180    of string, as it appears on command line (we'll discuss type checkers and
   184    of string, as it appears on command line (we'll discuss type checkers and
   181    what can they do to value later). Before parsing command line, parser will
   185    what can they do to value later).  Before parsing command line, parser will
   182    assign this value to corresponding value structure.
   186    assign this value to corresponding value structure.
   183 
   187 
   184  * 'type' - pointer to structure, describing argument type.
   188  * 'type' - pointer to structure, describing argument type.
   185 
   189 
   186  * 'chkdata' - if type needs some additional info, it is a place to supply it.
   190  * 'chkdata' - if type needs some additional info, it is a place to supply it.
   187 
   191 
   188  * 'userdata' - place for arbitrary info, that should accompany this argument or
   192  * 'userdata' - place for arbitrary info, that should accompany this argument or
   189    option. Unused by parser.
   193    option.  Unused by parser.
   190 
   194 
   191 Now, let's discuss general case - option with argument or positional argument.
   195 Now, let's discuss general case - option with argument or positional argument.
   192 
   196 
   193 When parser encounters such argument, it checks 'catchall' and 'plain' flags and
   197 When parser encounters such argument, it checks 'catchall' and 'plain' flags and
   194 crops argument value from command line accordingly, then it assigns it to the
   198 crops argument value from command line accordingly, then it assigns it to the
   195 'value.arg' field of 'cmdarg_value_t' struct in array 'values' with index, given
   199 'value.arg' field of 'cmdarg_value_t' struct in array 'values' with index, given
   196 in 'pos'. Also it marks such value as 'visited' and puts a link to argument
   200 in 'pos'.  Also it marks such value as 'visited' and puts a link to argument
   197 description into value's 'src' field. More about effect of these actions later,
   201 description into value's 'src' field.  More about effect of these actions later,
   198 in 'cmdarg_value_t' section.
   202 in 'cmdarg_value_t' section.
   199 
   203 
   200 However, if argument struct is a part of option description struct, and have
   204 However, if argument struct is a part of option description struct, and have
   201 flag 'switch' set, parser will not try to parse value. Instead it will increase
   205 flag 'switch' set, parser will not try to parse value.  Instead it will increase
   202 the count in 'value.swc' in corresponding 'cmdarg_value_t' struct. Argument name
   206 the count in 'value.swc' in corresponding 'cmdarg_value_t' struct.  Argument
   203 for switches is essentially ignored, but for safety sake it is recommended to
   207 name for switches is essentially ignored, but for safety sake it is recommended
   204 duplicate switch long option name here. Flags 'catchall' and 'plain' obviously
   208 to duplicate switch long option name here.  Flags 'catchall' and 'plain'
   205 have no effect. Flag 'check' makes switch a trigger, that flips between 'on' and
   209 obviously have no effect.  Flag 'check' makes switch a trigger, that flips
   206 'off' for every occurence of flag on command line. Flags 'required' and 'subcmd'
   210 between 'on' and 'off' for every occurence of flag on command line.  Flags
   207 also have no effect for obvious reasons. Default value is ignored for switches,
   211 'required' and 'subcmd' also have no effect for obvious reasons.  Default value
   208 they always start with count 0 (off). Since switch is internal type, argument
   212 is ignored for switches, they always start with count 0 (off).  Since switch is
   209 type field is ignored as well. Flags and source fields of value are updated as
   213 internal type, argument type field is ignored as well.  Flags and source fields
   210 usual.
   214 of value are updated as usual.
   211 
   215 
   212 If flag 'subcmd' is set for positional argument, parser crops argument value
   216 If flag 'subcmd' is set for positional argument, parser crops argument value
   213 according to flags as usual, but instead of assigning it, walks through list of
   217 according to flags as usual, but instead of assigning it, walks through list of
   214 subcommands in command description struct and compares obtained value to
   218 subcommands in command description struct and compares obtained value to
   215 subcommand names. If it finds corresponding subcommand, it assigns pointer to
   219 subcommand names.  If it finds corresponding subcommand, it assigns pointer to
   216 subcommand description struct to 'value.cmd' field of corresponding
   220 subcommand description struct to 'value.cmd' field of corresponding
   217 'cmdarg_value_t' struct and updates it's source and flags. Then, instead of
   221 'cmdarg_value_t' struct and updates it's source and flags.  Then, instead of
   218 proceeding with parsing process, it recursively calls parser on remaining part
   222 proceeding with parsing process, it recursively calls parser on remaining part
   219 of command line, passing subparser subcommand description. Note, that if
   223 of command line, passing subparser subcommand description.  Note, that if
   220 subcommand parser will end parsing before hitting end of command line, parser
   224 subcommand parser will end parsing before hitting end of command line, parser
   221 will proceed with parsing arguments for main command. Default value and argument
   225 will proceed with parsing arguments for main command.  Default value and
   222 type fields are ignored for subcommands.
   226 argument type fields are ignored for subcommands.
   223 
   227 
   224 Now let's take a look at value structure, that you'll be dealing with the most
   228 Now let's take a look at value structure, that you'll be dealing with the most
   225 in the actual code.
   229 in the actual code.
   226 
   230 
   227 ## Argument value structure, 'cmdarg_value_t'
   231 ## Argument value structure, 'cmdarg_value_t'
   228 
   232 
   229 [[!format c """ // -------------------------------------------------------------
   233 [[!format c """// --------------------------------------------------------------
   230 
   234 
   231 typedef struct cmdarg_value_struct cmdarg_value_t;
   235 typedef struct cmdarg_value_struct cmdarg_value_t;
   232 
   236 
   233 typedef enum {
   237 typedef enum {
   234     cmdval_default = 0x0000,
   238     cmdval_default = 0x0000,
   235     cmdval_visited = 0x0100,
   239     cmdval_visited = 0x0100,
   236     cmdval_freeme  = 0x0200,
   240     cmdval_freeme  = 0x0200,
   237 } cmdval_flags_t;
   241 } cmdval_flags_t;
   238 
   242 
   239 struct cmdarg_value_struct {
   243 struct cmdarg_value_struct {
   240     cmdarg_t       *src;
   244     const cmdarg_t *src;
   241     cmdval_flags_t flags;
   245     cmdval_flags_t flags;
   242     union {
   246     union {
   243         guint        uint;
   247         guint           uint;
   244         gint         sint;
   248         gint            sint;
   245         guint        swc;
   249         guint           swc;
   246         const gchar  *roarg;
   250         const gchar     *roarg;
   247         gchar        *arg;
   251         gchar           *arg;
   248         cmdopts_t    *cmd;
   252         const cmdopts_t *cmd;
   249         struct {
   253         struct {
   250             gpointer   bud;
   254             gpointer    bud;
   251             gchar      *resource;
   255             gchar       *resource;
   252         } rjid;
   256         } rjid;
   253         gpointer     ptr;
   257         gpointer        ptr;
   254     } value;
   258     } value;
   255 };
   259 };
   256 
   260 
   257 // -------------------------------------------------------------      """     ]]
   261 // --------------------------------------------------------------     """     ]]
   258 
   262 
   259 Command may happen to be called recursively - i.e., something in command may
   263 Command may happen to be called recursively - i.e., something in command may
   260 cause the event, that will cause another call to the same command, thus we
   264 cause the event, that will cause another call to the same command, thus we
   261 cannot store actual values in command/argument definition struct, and have to
   265 cannot store actual values in command/argument definition struct, and have to
   262 allocate dynamic memory for them. This struct is designed exactly for this.
   266 allocate dynamic memory for them.  This struct is designed exactly for this.
   263 Let's take a look at it's fields:
   267 Let's take a look at it's fields:
   264 
   268 
   265  * 'src' - this points to the argument description, from which this struct is
   269  * 'src' - this points to the argument description, from which this struct is
   266    holding value right now (note, that value can be initialized several times
   270    holding value right now (note, that value can be initialized several times
   267    during parsing process from different arguments).
   271    during parsing process from different arguments).
   289 
   293 
   290 ## Parsing
   294 ## Parsing
   291 
   295 
   292 Parser starts by allocating memory for values array, and then initializing it by
   296 Parser starts by allocating memory for values array, and then initializing it by
   293 walking through command description, looking at options and arguments and
   297 walking through command description, looking at options and arguments and
   294 assigning default values to corresponding entries in array. It also puts pointer
   298 assigning default values to corresponding entries in array.  It also puts
   295 to the argument description into value's 'src' field. Thus, all used in command
   299 pointer to the argument description into value's 'src' field.  Thus, all used in
   296 description values will have this field initialized, even if they were not
   300 command description values will have this field initialized, even if they were
   297 specified on command line. This comes handly later, when checking for reqired
   301 not specified on command line.  This comes handly later, when checking for
   298 value presence. For switches parser just sets the counter to zero. Note, that
   302 reqired value presence.  For switches parser just sets the counter to zero.
   299 parser does not descend into subcommands at this stage. It does the same
   303 Note, that parser does not descend into subcommands at this stage.  It does the
   300 procedure for subcommand, but later, when it already knows which subcommand is
   304 same procedure for subcommand, but later, when it already knows which subcommand
   301 selected. Also note, that if several arguments have the same value index, parser
   305 is selected.  Also note, that if several arguments have the same value index,
   302 will use latest encountered one to initialize the value. This is used for
   306 parser will use latest encountered one to initialize the value.  This is used
   303 default value in "argument clustering", that I'll show you later.
   307 for default value in "argument clustering", that I'll show you later.
   304 
   308 
   305 Then parser calls command environment checker callback (if present), and if it
   309 Then parser calls command environment checker callback (if present), and if it
   306 returns error - terminates the process right now. Note, that subcommands can
   310 returns error - terminates the process right now.  Note, that subcommands can
   307 also have checkers.
   311 also have checkers.
   308 
   312 
   309 Next parser does its job of parsing command line. Each time it extracts argument
   313 Next parser does its job of parsing command line.  Each time it extracts
   310 value, it into 'value.arg' field of corresponding value entry and pointer to
   314 argument value, it into 'value.arg' field of corresponding value entry and
   311 argument description struct into 'src' field. Also it sets 'visited' flag on
   315 pointer to argument description struct into 'src' field.  Also it sets 'visited'
   312 value. At this stage value is still just unchecked string, except for special
   316 flag on value.  At this stage value is still just unchecked string, except for
   313 argument types. For switch occurence count in 'value.swc' gets increased each
   317 special argument types.  For switch occurence count in 'value.swc' gets
   314 time argument was specified. Note however, that if several switches use the same
   318 increased each time argument was specified.  Note however, that if several
   315 value index ("clustered switches"), counter gets reset, when switches change one
   319 switches use the same value index ("clustered switches"), counter gets reset,
   316 another in sequence - i.e. "-e -s -s -s" will count as three "-s", but "-s -s -e
   320 when switches change one another in sequence - i.e. "-e -s -s -s" will count as
   317 -s" will count as only one "-s". For subcommands parser checks for corresponding
   321 three "-s", but "-s -s -e -s" will count as only one "-s".  For subcommands
   318 subcommand in 'cmds' list, assigns it to 'value.cmd' and recursively passes the
   322 parser checks for corresponding subcommand in 'cmds' list, assigns it to
   319 end of command line to be parsed with subcommand description. Note, that for
   323 'value.cmd' and recursively passes the end of command line to be parsed with
   320 subcommands parser does "checking on the spot" - if parsed argument value does
   324 subcommand description.  Note, that for subcommands parser does "checking on the
   321 not match any subcommand, and argument have 'required' flag set, it raises error
   325 spot" - if parsed argument value does not match any subcommand, and argument
   322 immediately (if flag is not set, it merely assigns NULL and proceeds parsing
   326 have 'required' flag set, it raises error immediately (if flag is not set, it
   323 according to current command description).
   327 merely assigns NULL and proceeds parsing according to current command
   324 
   328 description).
   325 Then parser walks through array of values and performs value checking. Note,
   329 
       
   330 Then parser walks through array of values and performs value checking.  Note,
   326 that all values, that need checking at this point should have 'src' field
   331 that all values, that need checking at this point should have 'src' field
   327 initialized - either set at default value assignment step, or during parsing,
   332 initialized - either set at default value assignment step, or during parsing,
   328 so, parser knows properties of value's argument. Parser only pays attention to
   333 so, parser knows properties of value's argument.  Parser only pays attention to
   329 the values, that either have 'visited' flag set (i.e. provided by user) or that
   334 the values, that either have 'visited' flag set (i.e. provided by user) or that
   330 have 'check' flag in argument description (useful for mandatory arguments or
   335 have 'check' flag in argument description (useful for mandatory arguments or
   331 default values, that need convesion). If value corresponds to a switch, and
   336 default values, that need convesion).  If value corresponds to a switch, and
   332 argument have 'check' flag set, switch occurence count is replaced by remainder
   337 argument have 'check' flag set, switch occurence count is replaced by remainder
   333 of division it by 2 (this way switch behaves like trigger). If it is a
   338 of division it by 2 (this way switch behaves like trigger).  If it is a
   334 subcommand, and it have 'required' flag set, parser checks, if it have non-NULL
   339 subcommand, and it have 'required' flag set, parser checks, if it have non-NULL
   335 value. If it is usual argument (option or positional), and it does have 'type',
   340 value.  If it is usual argument (option or positional), and it does have 'type',
   336 that have 'check' callback set, parser calls this checker, passing it value
   341 that have 'check' callback set, parser calls this checker, passing it value
   337 structure (again, value structure contains pointer to argument description, so,
   342 structure (again, value structure contains pointer to argument description, so,
   338 checker can access 'chkdata' field, supplied by user). If checker returns error
   343 checker can access 'chkdata' field, supplied by user).  If checker returns error
   339 string and argument have 'required' flag set, parser raises error. If flag is
   344 string and argument have 'required' flag set, parser raises error.  If flag is
   340 not set, parser just prints warning and proceeds with checking.
   345 not set, parser just prints warning and proceeds with checking.
   341 
   346 
   342 If checking was successful, parser calls command function, providing it with
   347 If checking was successful, parser calls command function, providing it with
   343 command description and values array. This function can also return error, but
   348 command description and values array.  This function can also return error, but
   344 at this stage it does not change process, only causes error message to be
   349 at this stage it does not change process, only causes error message to be
   345 printed.
   350 printed.
   346 
   351 
   347 And finally parser frees allocated resources - walks through values array,
   352 And finally parser frees allocated resources - walks through values array,
   348 calling argument type 'free' callback on values, that have 'freeme' flag set and
   353 calling argument type 'free' callback on values, that have 'freeme' flag set and
   349 then frees the array itself.
   354 then frees the array itself.
   350 
   355 
   351 ## Argument type, 'cmdarg_type_t'
   356 ## Argument type, 'cmdarg_type_t'
   352 
   357 
   353 [[!format c """ // -------------------------------------------------------------
   358 [[!format c """// --------------------------------------------------------------
   354 
   359 
   355 typedef struct cmdarg_type_struct cmdarg_type_t;
   360 typedef struct cmdarg_type_struct cmdarg_type_t;
   356 
   361 
   357 typedef gchar *(*cmdarg_checker_t) (cmdarg_value_t *value);
   362 typedef gchar *(*cmdarg_checker_t) (cmdarg_value_t *value);
   358 typedef void (*cmdarg_destructor_t) (cmdarg_value_t *value);
   363 typedef void (*cmdarg_destructor_t) (cmdarg_value_t *value);
   363     cmdarg_checker_t    check;
   368     cmdarg_checker_t    check;
   364     cmdarg_destructor_t free;
   369     cmdarg_destructor_t free;
   365     cmdarg_completor_t  complete;
   370     cmdarg_completor_t  complete;
   366 };
   371 };
   367 
   372 
   368 // -------------------------------------------------------------      """     ]]
   373 // --------------------------------------------------------------     """     ]]
   369 
   374 
   370 As you can see, argument type is nothing more than a set of callbacks:
   375 As you can see, argument type is nothing more than a set of callbacks:
   371 
   376 
   372  * 'check' - check parsed argument value for conformance to type rules, possibly
   377  * 'check' - check parsed argument value for conformance to type rules, possibly
   373    replace with something different, like corresponding integer value or roster
   378    replace with something different, like corresponding integer value or roster
   375 
   380 
   376  * 'free' - if type checker may need to free some data afterwards, this callback
   381  * 'free' - if type checker may need to free some data afterwards, this callback
   377    should be set to corresponding function, and each time checker really needs
   382    should be set to corresponding function, and each time checker really needs
   378    value to be freed, it should set flag 'freeme' on value.
   383    value to be freed, it should set flag 'freeme' on value.
   379 
   384 
   380  * 'complete' - FIXME not yet designed callback, that will return list of
   385  * 'complete' - *FIXME* not yet designed callback, that will return list of
   381    possible completions according to given prefix.
   386    possible completions according to given prefix.
   382 
   387 
   383 After parsing command line parser performs argument value checking, that's where
   388 After parsing command line parser performs argument value checking, that's where
   384 it calls 'check' callbacks.  Checker is given pointer to value structure, that
   389 it calls 'check' callbacks.   Checker is given pointer to value structure, that
   385 it needs to check. Checker can modify value string (except when it is default
   390 it needs to check.  Checker can modify value string (except when it is default
   386 value, but you have to supply your default values so, that they do not need
   391 value, but you have to supply your default values so, that they do not need
   387 modifying) or completely replace it with another string or even non-string
   392 modifying) or completely replace it with another string or even non-string
   388 object. If checker uses some resources (eg. allocates memory for replacement
   393 object.  If checker uses some resources (eg.  allocates memory for replacement
   389 value), it can set the flag 'freeme' on value to request call to value
   394 value), it can set the flag 'freeme' on value to request call to value
   390 destructor, when values array will be freed. If checker needs some additional
   395 destructor, when values array will be freed.  If checker needs some additional
   391 data (eg. it is some generic checker, that needs list of valid values or other
   396 data (eg. it is some generic checker, that needs list of valid values or other
   392 parameters), these data can be supplied in 'chkdata' field. Checker function
   397 parameters), these data can be supplied in 'chkdata' field.  Checker function
   393 should return NULL on success or error string, that will be g_free()'d by
   398 should return NULL on success or error string, that will be g_free()'d by
   394 parser. Take note, that if argument does not have 'reqired' flag set, parser
   399 parser.  Take note, that if argument does not have 'reqired' flag set, parser
   395 will ignore checker error, so, it is recommended to nullify invalid value before
   400 will ignore checker error, so, it is recommended to nullify invalid value before
   396 returning error (but it is not required).
   401 returning error (but it is not required).
   397 
   402 
   398 # Examples
   403 # Examples
   399 
   404 
   400 When writing description for a command, first thing, you have to do - is to
   405 When writing description for a command, first thing, you have to do - is to
   401 determine, which values your command can get from user. You don't have to be
   406 determine, which values your command can get from user.  You don't have to be
   402 shy - new interface is designed to encourage commands to be as flexible and
   407 shy - new interface is designed to encourage commands to be as flexible and
   403 option-rich as possible. 
   408 option-rich as possible.  
   404 
   409 
   405 Second - consider, which ones are to be specified as positional arguments, and
   410 Second - consider, which ones are to be specified as positional arguments, and
   406 which should become options or switches.
   411 which should become options or switches.
   407 
   412 
   408 Next you will want to decide, which checks and restrictions should you put on
   413 Next you will want to decide, which checks and restrictions should you put on
   409 values. Essentially, determine value type.
   414 values.  Essentially, determine value type.
   410 
   415 
   411 And then you can begin writing command definition. So, let's start with
   416 And then you can begin writing command definition.  So, let's start with
   412 something simple.
   417 something simple.
   413 
   418 
   414 ## Single-argument no-checks command
   419 ## Single-argument no-checks command
   415 
   420 
   416 Let's look at command like /say, that have only one argument, that should be
   421 Let's look at command like /say, that have only one argument, that should be
   418 
   423 
   419     /ex1 message...
   424     /ex1 message...
   420 
   425 
   421 Definition for such command will look like:
   426 Definition for such command will look like:
   422 
   427 
   423 [[!format c """ // -------------------------------------------------------------
   428 [[!format c """// --------------------------------------------------------------
   424 
   429 
   425 // command function predeclaration
   430 // command function predeclaration
   426 gchar *do_ex1 (cmdopts_t *command, cmdarg_value_t *values);
   431 gchar *do_ex1 (const cmdopts_t *command, cmdarg_value_t *values);
   427 
   432 
   428 // command arguments definition
   433 // command arguments definition
   429 cmdopts_t def_ex1 = {
   434 cmdopts_t def_ex1 = {
   430     "ex1",              // command name
   435     "ex1",              // command name
   431     cmd_default,        // flags
   436     cmd_default,        // flags
   447     },
   452     },
   448     NULL,               // list of subcommands - none
   453     NULL,               // list of subcommands - none
   449 };
   454 };
   450 
   455 
   451 // Command function gets shown above command description (we don't need it) and
   456 // Command function gets shown above command description (we don't need it) and
   452 // argument value list. Returns error message or NULL.
   457 // argument value list.  Returns error message or NULL.
   453 gchar *do_ex1 (cmdopts_t *command, cmdarg_value_t *values)
   458 gchar *do_ex1 (const cmdopts_t *command, cmdarg_value_t *values)
   454 {
   459 {
   455     gchar *message = values[0].value.arg;
   460     gchar *message = values[0].value.arg;
   456     // now do something with message:
   461     // now do something with message:
   457     // - check, if message was given at all
   462     // - check, if message was given at all
   458     if (!message || !*message)
   463     if (!message || !*message)
   470 ...
   475 ...
   471 // remove command
   476 // remove command
   472 cmd_undef (&def_ex1);
   477 cmd_undef (&def_ex1);
   473 ...
   478 ...
   474 
   479 
   475 [[!format c """ // -------------------------------------------------------------
   480 [[!format c """// --------------------------------------------------------------
   476 
   481 
   477 A lot of things to do to achieve a simple goal - does not look quite appealing
   482 A lot of things to do to achieve a simple goal - does not look quite appealing
   478 so far. Still, let's tweak our example a bit.
   483 so far.  Still, let's tweak our example a bit.
   479 
   484 
   480 Remember the third step - decide, which checks should apply to our argument.
   485 Remember the third step - decide, which checks should apply to our argument.
   481 Now, look at our command - we check, if message is NULL or if message is empty.
   486 Now, look at our command - we check, if message is NULL or if message is empty.
   482 But imagine, that user has given us a message " " - it's of no big use to us,
   487 But imagine, that user has given us a message " " - it's of no big use to us,
   483 so, probably, we should also strip leading/trailing spaces before doing the
   488 so, probably, we should also strip leading/trailing spaces before doing the
   484 check. That's where argument types come into play. We can write argument
   489 check.  That's where argument types come into play.  We can write argument
   485 checker for that! But luckily, we already have built-in standard checker, that
   490 checker for that! But luckily, we already have built-in standard checker, that
   486 does exactly what we need - checks if string contains non-space characters. All
   491 does exactly what we need - checks if string contains non-space characters.  All
   487 we need to do - to specify '&cmdarg_type_nonspace' as argument type and remove
   492 we need to do - to specify '&cmdarg_type_nonspace' as argument type and remove
   488 our check inside of the command:
   493 our check inside of the command:
   489 
   494 
   490 [[!format c """ // -------------------------------------------------------------
   495 [[!format c """// --------------------------------------------------------------
   491 
   496 
   492 ...
   497 ...
   493 cmdopts_t def_ex1 = {
   498 cmdopts_t def_ex1 = {
   494     "ex1",
   499     "ex1",
   495     cmd_default,
   500     cmd_default,
   516         {NULL}
   521         {NULL}
   517     },
   522     },
   518     NULL,
   523     NULL,
   519 };
   524 };
   520 
   525 
   521 gchar *do_ex1 (cmdopts_t *command, cmdarg_value_t *values)
   526 gchar *do_ex1 (const cmdopts_t *command, cmdarg_value_t *values)
   522 {
   527 {
   523     scr_log_print (LPRINT_NORMAL, "Got the message: \"%s\".",
   528     scr_log_print (LPRINT_NORMAL, "Got the message: \"%s\".",
   524                    values[0].value.arg);
   529                    values[0].value.arg);
   525     return NULL;
   530     return NULL;
   526 }
   531 }
   527 ...
   532 ...
   528 
   533 
   529 // -------------------------------------------------------------      """     ]]
   534 // --------------------------------------------------------------     """     ]]
   530 
   535 
   531 Ok, that's a little bit better. Now let's move on to something more complex.
   536 Ok, that's a little bit better.  Now let's move on to something more complex.
   532 
   537 
   533 ## Switches
   538 ## Switches
   534 
   539 
   535 Let's add switches '-s' and '-l', that will define, where to print the message
   540 Let's add switches '-s' and '-l', that will define, where to print the message
   536 to - to log or to screen. For that we will need another two value indices - one
   541 to - to log or to screen.  For that we will need another two value indices - one
   537 for each switch.
   542 for each switch.
   538 
   543 
   539 [[!format c """ // -------------------------------------------------------------
   544 [[!format c """// --------------------------------------------------------------
   540 
   545 
   541 ...
   546 ...
   542 cmdopts_t def_ex1 = {
   547 cmdopts_t def_ex1 = {
   543     "ex1",
   548     "ex1",
   544     cmd_default,
   549     cmd_default,
   568         {NULL}
   573         {NULL}
   569     },
   574     },
   570     NULL,
   575     NULL,
   571 };
   576 };
   572 
   577 
   573 gchar *do_ex1 (cmdopts_t *command, cmdarg_value_t *values)
   578 gchar *do_ex1 (const cmdopts_t *command, cmdarg_value_t *values)
   574 {
   579 {
   575     // default value
   580     // default value
   576     guint whereto = LPRINT_NORMAL;
   581     guint whereto = LPRINT_NORMAL;
   577     // -s is default, so, check, that it is not set before checking for -l
   582     // -s is default, so, check, that it is not set before checking for -l
   578     if (!values[1].value.swc)
   583     if (!values[1].value.swc)
   581     scr_log_print (whereto, "Got the message: \"%s\".", values[0].value.arg);
   586     scr_log_print (whereto, "Got the message: \"%s\".", values[0].value.arg);
   582     return NULL;
   587     return NULL;
   583 }
   588 }
   584 ...
   589 ...
   585 
   590 
   586 // -------------------------------------------------------------      """     ]]
   591 // --------------------------------------------------------------     """     ]]
   587 
   592 
   588 Ok, that works, but what if user have aliases, and wants last specified option
   593 Ok, that works, but what if user have aliases, and wants last specified option
   589 to override the value? Currently, if -s was once specified, -l will not have any
   594 to override the value? Currently, if -s was once specified, -l will not have any
   590 effect, regardless of count or position in command line. Not that good. Let's
   595 effect, regardless of count or position in command line.  Not that good.  Let's
   591 use the trick, that I call "argument clustering". We'll specify the same value
   596 use the trick, that I call "argument clustering".  We'll specify the same value
   592 index for both switches. Since 'value' struct have the pointer to the argument,
   597 index for both switches.  Since 'value' struct have the pointer to the argument,
   593 it was initialized from last time, we can recognize, which switch was used last.
   598 it was initialized from last time, we can recognize, which switch was used last.
   594 By default this pointer points to the last argument with this index in command
   599 By default this pointer points to the last argument with this index in command
   595 definition - we can use that to specify default value. Now, to identify switches
   600 definition - we can use that to specify default value.  Now, to identify
   596 we can use argument names, but 'argument' struct contains userdata field, where
   601 switches we can use argument names, but 'argument' struct contains userdata
   597 we can put our LPRINT_* constants and just use it directly. So, with clustered
   602 field, where we can put our LPRINT_* constants and just use it directly.  So,
   598 switches, we will have:
   603 with clustered switches, we will have:
   599 
   604 
   600 [[!format c """ // -------------------------------------------------------------
   605 [[!format c """// --------------------------------------------------------------
   601 
   606 
   602 ...
   607 ...
   603 cmdopts_t def_ex1 = {
   608 cmdopts_t def_ex1 = {
   604     "ex1",
   609     "ex1",
   605     cmd_default,
   610     cmd_default,
   606     NULL,
   611     NULL,
   607     do_ex1,
   612     do_ex1,
   608     (cmdopt_t[3]){
   613     (cmdopt_t[3]){
   609         // Set both argument indices to 1, specify our constants in userdata
   614         // Set both argument indices to 1, specify our constants in userdata
   610         // field. Screen is default value, thus, it goes last.
   615         // field.  Screen is default value, thus, it goes last.
   611         { 'l', "log",    { "log",    1, cmdarg_switch, NULL, NULL, NULL,
   616         { 'l', "log",    { "log",    1, cmdarg_switch, NULL, NULL, NULL,
   612                              (gpointer)LPRINT_LOG    } },
   617                              (gpointer)LPRINT_LOG    } },
   613         { 's', "screen", { "screen", 1, cmdarg_switch, NULL, NULL, NULL,
   618         { 's', "screen", { "screen", 1, cmdarg_switch, NULL, NULL, NULL,
   614                              (gpointer)LPRINT_NORMAL } },
   619                              (gpointer)LPRINT_NORMAL } },
   615         {0}
   620         {0}
   620         {NULL}
   625         {NULL}
   621     },
   626     },
   622     NULL,
   627     NULL,
   623 };
   628 };
   624 
   629 
   625 gchar *do_ex1 (cmdopts_t *command, cmdarg_value_t *values)
   630 gchar *do_ex1 (const cmdopts_t *command, cmdarg_value_t *values)
   626 {
   631 {
   627     scr_log_print ((guint)values[1].src -> userdata,
   632     scr_log_print ((guint)values[1].src -> userdata,
   628                    "Got the message: \"%s\".", values[0].value.arg);
   633                    "Got the message: \"%s\".", values[0].value.arg);
   629     return NULL;
   634     return NULL;
   630 }
   635 }
   631 ...
   636 ...
   632 
   637 
   633 // -------------------------------------------------------------      """     ]]
   638 // --------------------------------------------------------------     """     ]]
   634 
   639 
   635 That's much better. This trick may be quite useful not only with switches, but
   640 That's much better.  This trick may be quite useful not only with switches, but
   636 also with options, sometimes even clustering options with arguments can be
   641 also with options, sometimes even clustering options with arguments can be
   637 handy.
   642 handy.
   638 
   643 
   639 ## Options
   644 ## Options
   640 
   645 
   641 Options are not much different from normal arguments, except there you'll see
   646 Options are not much different from normal arguments, except there you'll see
   642 'check' and 'required' mostly only in combination with default value - otherwise
   647 'check' and 'required' mostly only in combination with default value - otherwise
   643 it defeats the purpose - to be optional.
   648 it defeats the purpose - to be optional.
   644 
   649 
   645 [[!format c """ // -------------------------------------------------------------
   650 [[!format c """// --------------------------------------------------------------
   646 
   651 
   647 // TODO:
   652 // TODO:
   648 //   example (not really used as of now - were too complex to deal using old
   653 //   example (not really used as of now - were too complex to deal using old
   649 //   interface).
   654 //   interface).
   650 
   655 
   651 // -------------------------------------------------------------      """     ]]
   656 // --------------------------------------------------------------     """     ]]
   652 
   657 
   653 ## Subcommands
   658 ## Subcommands
   654 
   659 
   655 Now, let's discuss another internal argument type - subcommand. Since
   660 Now, let's discuss another internal argument type - subcommand.  Since
   656 subcommands are quite common in mcabber, and since they have quite big impact on
   661 subcommands are quite common in mcabber, and since they have quite big impact on
   657 parsing process, they were made a part of parser.
   662 parsing process, they were made a part of parser.
   658 
   663 
   659 Currently, only positional arguments can be subcommands. You can have options or
   664 Currently, only positional arguments can be subcommands.  You can have options or
   660 other arguments precede them, though in practice there's no examples of that so
   665 other arguments precede them, though in practice there's no examples of that so
   661 far.
   666 far.
   662 
   667 
   663 So, to indicate, that argument is a subcommand, you just add flag 'subcmd'. When
   668 So, to indicate, that argument is a subcommand, you just add flag 'subcmd'.
   664 parser will encounter such argument, it will look up command structure with
   669 When parser will encounter such argument, it will look up command structure with
   665 specified name in the list 'cmds' of command definition and proceed parsing,
   670 specified name in the list 'cmds' of command definition and proceed parsing,
   666 using that command definition instead of main one. A good example of command
   671 using that command definition instead of main one.  A good example of command
   667 with several completely different subcommands would be '/color', so, let's look:
   672 with several completely different subcommands would be '/color', so, let's look:
   668 
   673 
   669 [[!format c """ // -------------------------------------------------------------
   674 [[!format c """// --------------------------------------------------------------
   670 
   675 
   671 static gchar *do_color (cmdopts_t *command, cmdarg_value_t *values);
   676 static gchar *do_color (const cmdopts_t *command, cmdarg_value_t *values);
   672 
   677 
   673 // We will put these values in subcommand definition 'userdata' fields
   678 // We will put these values in subcommand definition 'userdata' fields
   674 // to simplify the task of determining, which subcommand was actually selected.
   679 // to simplify the task of determining, which subcommand was actually selected.
   675 typedef enum {
   680 typedef enum {
   676     scmd_color_roster,
   681     scmd_color_roster,
   749             }, NULL, (gpointer)scmd_color_mucnick},
   754             }, NULL, (gpointer)scmd_color_mucnick},
   750         {NULL}
   755         {NULL}
   751     },
   756     },
   752 };
   757 };
   753 
   758 
   754 static gchar *do_color (cmdopts_t *options, cmdarg_value_t *values)
   759 static gchar *do_color (const cmdopts_t *options, cmdarg_value_t *values)
   755 {
   760 {
   756     scmd_color_t subcmd =
   761     scmd_color_t subcmd =
   757                   (scmd_color_t) (values[pos_color_scmd].value.cmd -> userdata);
   762                   (scmd_color_t) (values[pos_color_scmd].value.cmd -> userdata);
   758 
   763 
   759     if (subcmd == scmd_color_roster) {
   764     if (subcmd == scmd_color_roster) {
   782     }
   787     }
   783 
   788 
   784     return NULL;
   789     return NULL;
   785 }
   790 }
   786 
   791 
   787 // -------------------------------------------------------------      """     ]]
   792 // --------------------------------------------------------------     """     ]]
   788 
   793 
   789 Here you also see a lot of new types:
   794 Here you also see a lot of new types:
   790 
   795 
   791  * 'color_statusmask' - specific to "/color" command wrapper over generic type
   796  * 'color_statusmask' - specific to "/color" command wrapper over generic type
   792    'charset'.  This type allows only word "clear" or string, composed of
   797    'charset'.  This type allows only word "clear" or string, composed of
   808 
   813 
   809 ## Argument types
   814 ## Argument types
   810 
   815 
   811 Let's take a look at simple checker, that we've encountered first - 'nonspace':
   816 Let's take a look at simple checker, that we've encountered first - 'nonspace':
   812 
   817 
   813 [[!format c """ // -------------------------------------------------------------
   818 [[!format c """// --------------------------------------------------------------
   814 
   819 
   815 // Checker gets parsed value string in 'value.arg', argument description in
   820 // Checker gets parsed value string in 'value.arg', argument description in
   816 // 'src' and returns error string or NULL.
   821 // 'src' and returns error string or NULL.
   817 gchar *cmdarg_check_nonspace (cmdarg_value_t *arg)
   822 gchar *cmdarg_check_nonspace (cmdarg_value_t *arg)
   818 {
   823 {
   857     NULL,
   862     NULL,
   858     // completion callabck - none, we can't know, what string may contain
   863     // completion callabck - none, we can't know, what string may contain
   859     NULL,
   864     NULL,
   860 };
   865 };
   861 
   866 
   862 // -------------------------------------------------------------      """     ]]
   867 // --------------------------------------------------------------     """     ]]
   863 
   868 
   864 Quite simple, I hope. Now, let's look at more complex type - 'fjid':
   869 Quite simple, I hope.  Now, let's look at more complex type - 'fjid':
   865 
   870 
   866 [[!format c """ // -------------------------------------------------------------
   871 [[!format c """// --------------------------------------------------------------
   867 
   872 
   868 // This checker checks syntax of fjid and expands "current-buddy" expressions
   873 // This checker checks syntax of fjid and expands "current-buddy" expressions
   869 // "." and "./resource".
   874 // "." and "./resource".
   870 gchar *cmdarg_check_fjid (cmdarg_value_t *arg)
   875 gchar *cmdarg_check_fjid (cmdarg_value_t *arg)
   871 {
   876 {
   921     // completor, while possible, is not implemented, as whole completion system is
   926     // completor, while possible, is not implemented, as whole completion system is
   922     // not yet designed.
   927     // not yet designed.
   923     NULL,
   928     NULL,
   924 };
   929 };
   925 
   930 
   926 // -------------------------------------------------------------      """     ]]
   931 // --------------------------------------------------------------     """     ]]
   927 
   932 
   928 If possible, you are encouraged to re-use existing checkers - for example, bjid
   933 If possible, you are encouraged to re-use existing checkers - for example, bjid
   929 checker uses fjid checker to expand "current-buddy" expressions and check
   934 checker uses fjid checker to expand "current-buddy" expressions and check
   930 syntax, and only strips resource afterwards:
   935 syntax, and only strips resource afterwards:
   931 
   936 
   932 [[!format c """ // -------------------------------------------------------------
   937 [[!format c """// --------------------------------------------------------------
   933 
   938 
   934 gchar *cmdarg_check_bjid (cmdarg_value_t *arg)
   939 gchar *cmdarg_check_bjid (cmdarg_value_t *arg)
   935 {
   940 {
   936     gchar *error = NULL;
   941     gchar *error = NULL;
   937 
   942 
   951     // may need to free value - we're using fjid checker internally
   956     // may need to free value - we're using fjid checker internally
   952     cmdarg_free_gfree,
   957     cmdarg_free_gfree,
   953     NULL,
   958     NULL,
   954 };
   959 };
   955 
   960 
   956 // -------------------------------------------------------------      """     ]]
   961 // --------------------------------------------------------------     """     ]]
   957 
   962 
   958 So far we've only modified string in value. But checkers are not limited to
   963 So far we've only modified string in value.  But checkers are not limited to
   959 this, for example, uint checker performs atoi() on value and assigns resulting
   964 this, for example, uint checker performs atoi() on value and assigns resulting
   960 number to value.uint. Take a look at definition of cmdarg_value_t struct - value
   965 number to value.uint.  Take a look at definition of cmdarg_value_t struct -
   961 is actually a union of different types of value. If you need something different
   966 value is actually a union of different types of value.  If you need something
   962 from existing - you can always allocate your own struct and use value.ptr.
   967 different from existing - you can always allocate your own struct and use
   963 However, if you think, that your case is generic enough - contact mcabber
   968 value.ptr.  However, if you think, that your case is generic enough - contact
   964 developers, we'll consider adding more variants there. Maybe we'll even add your
   969 mcabber developers, we'll consider adding more variants there.  Maybe we'll even
   965 argument type to built-in types.
   970 add your argument type to built-in types.
   966 
   971 
   967 <!-- vim: se ts=4 sw=4 et filetype=markdown tw=80: -->
   972 <!-- vim: se ts=4 sw=4 et filetype=markdown tw=80: -->