# getsubopt

## PROLOG



           This manual page is part of the POSIX Programmer's Manual.  The
           Linux implementation of this interface may differ (consult the
           corresponding Linux manual page for details of Linux behavior), or
           the interface may not be implemented on Linux.
    


## NAME



           getsubopt — parse suboption arguments from a string
    


## SYNOPSIS



           #include <stdlib.h>
    
           int getsubopt(char **_optionp_ , char * const *_keylistp_ , char **_valuep_);
    


## DESCRIPTION



           The _getsubopt_() function shall parse suboption arguments in a flag
           argument. Such options often result from the use of _getopt_().
    
           The _getsubopt_() argument _optionp_ is a pointer to a pointer to the
           option argument string. The suboption arguments shall be separated
           by <comma> characters and each may consist of either a single
           token, or a token-value pair separated by an <equals-sign>.
    
           The _keylistp_ argument shall be a pointer to a vector of strings.
           The end of the vector is identified by a null pointer. Each entry
           in the vector is one of the possible tokens that might be found in
           *_optionp_. Since <comma> characters delimit suboption arguments in
           _optionp_ , they should not appear in any of the strings pointed to
           by _keylistp_.  Similarly, because an <equals-sign> separates a
           token from its value, the application should not include an
           <equals-sign> in any of the strings pointed to by _keylistp_.  The
           _getsubopt_() function shall not modify the _keylistp_ vector.
    
           The _valuep_ argument is the address of a value string pointer.
    
           If a <comma> appears in _optionp_ , it shall be interpreted as a
           suboption separator. After <comma> characters have been processed,
           if there are one or more <equals-sign> characters in a suboption
           string, the first <equals-sign> in any suboption string shall be
           interpreted as a separator between a token and a value. Subsequent
           <equals-sign> characters in a suboption string shall be
           interpreted as part of the value.
    
           If the string at *_optionp_ contains only one suboption argument
           (equivalently, no <comma> characters), _getsubopt_() shall update
           *_optionp_ to point to the null character at the end of the string.
           Otherwise, it shall isolate the suboption argument by replacing
           the <comma> separator with a null character, and shall update
           *_optionp_ to point to the start of the next suboption argument. If
           the suboption argument has an associated value (equivalently,
           contains an <equals-sign>), _getsubopt_() shall update *_valuep_ to
           point to the value's first character.  Otherwise, it shall set
           *_valuep_ to a null pointer. The calling application may use this
           information to determine whether the presence or absence of a
           value for the suboption is an error.
    
           Additionally, when _getsubopt_() fails to match the suboption
           argument with a token in the _keylistp_ array, the calling
           application should decide if this is an error, or if the
           unrecognized option should be processed in another way.
    


## RETURN VALUE



           The _getsubopt_() function shall return the index of the matched
           token string, or -1 if no token strings were matched.
    


## ERRORS



           No errors are defined.
    
           _The following sections are informative._
    


## EXAMPLES



       **Parsing Suboptions**
           The following example uses the _getsubopt_() function to parse a
           _value_ argument in the _optarg_ external variable returned by a call
           to _getopt_().
    
               #include <stdio.h>
               #include <stdlib.h>
               #include <unistd.h>
    
               int do_all;
               const char *type;
               int read_size;
               int write_size;
               int read_only;
    
               enum
               {
                   RO_OPTION = 0,
                   RW_OPTION,
                   READ_SIZE_OPTION,
                   WRITE_SIZE_OPTION
               };
    
               const char *mount_opts[] =
               {
                   [RO_OPTION] = "ro",
                   [RW_OPTION] = "rw",
                   [READ_SIZE_OPTION] = "rsize",
                   [WRITE_SIZE_OPTION] = "wsize",
                   NULL
               };
    
               int
               main(int argc, char *argv[])
               {
                   char *subopts, *value;
                   int opt;
    
                   while ((opt = getopt(argc, argv, "at:o:")) != -1)
                       switch(opt)
                           {
                           case 'a':
                               do_all = 1;
                               break;
                           case 't':
                               type = optarg;
                               break;
                           case 'o':
                               subopts = optarg;
                               while (*subopts != ' ')
                               {
                                   char *saved = subopts;
                                   switch(getsubopt(&subopts, (char **)mount_opts,
                                       &value))
                                   {
                                   case RO_OPTION:
                                       read_only = 1;
                                       break;
                                   case RW_OPTION:
                                       read_only = 0;
                                       break;
                                   case READ_SIZE_OPTION:
                                       if (value == NULL)
                                           abort();
                                       read_size = atoi(value);
                                       break;
                                   case WRITE_SIZE_OPTION:
                                       if (value == NULL)
                                           abort();
                                       write_size = atoi(value);
                                       break;
                                   default:
                                       /* Unknown suboption. */
                                       printf("Unknown suboption `%s'\n", saved);
                                       abort();
                                   }
                               }
                               break;
                           default:
                               abort();
                           }
    
                   /* Do the real work. */
    
                   return 0;
               }
    
           If the above example is invoked with:
    
               program -o ro,rsize=512
    
           then after option parsing, the variable _do_all_ will be 0, _type_
           will be a null pointer, _read_size_ will be 512, _write_size_ will be
           0, and _read_only_ will be 1. If it is invoked with:
    
               program -o oops
    
           it will print:
    
               "Unknown suboption `oops'"
    
           before aborting.
    


## APPLICATION USAGE



           The value of *_valuep_ when _getsubopt_() returns -1 is unspecified.
           Historical implementations provide various incompatible extensions
           to allow an application to access the suboption text that was not
           found in the _keylistp_ array.
    


## RATIONALE



           The _keylistp_ argument of _getsubopt_() is typed as **char * const *** to
           match historical practice. However, the standard is clear that
           implementations will not modify either the array or the strings
           contained in the array, as if the argument had been typed **const**
           **char * const ***.
    


## FUTURE DIRECTIONS



           None.
    


* * *