iPXE
Defines | Functions
parseopt.c File Reference

Command line option parsing. More...

#include <stddef.h>
#include <stdint.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#include <getopt.h>
#include <ipxe/netdevice.h>
#include <ipxe/menu.h>
#include <ipxe/settings.h>
#include <ipxe/params.h>
#include <ipxe/timer.h>
#include <ipxe/parseopt.h>
#include <config/branding.h>

Go to the source code of this file.

Defines

#define ECANCELED_NO_OP   __einfo_error ( EINFO_ECANCELED_NO_OP )
 Return status code for "--help" option.
#define EINFO_ECANCELED_NO_OP   __einfo_uniqify ( EINFO_ECANCELED, 0x01, "Nothing to do" )
#define EINVAL_INTEGER   __einfo_error ( EINFO_EINVAL_INTEGER )
#define EINFO_EINVAL_INTEGER   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid integer value" )
#define EINVAL_UNKNOWN_OPTION   __einfo_error ( EINFO_EINVAL_UNKNOWN_OPTION )
#define EINFO_EINVAL_UNKNOWN_OPTION   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Unrecognised option" )
#define EINVAL_MISSING_ARGUMENT   __einfo_error ( EINFO_EINVAL_MISSING_ARGUMENT )
#define EINFO_EINVAL_MISSING_ARGUMENT   __einfo_uniqify ( EINFO_EINVAL, 0x03, "Missing argument" )

Functions

 FILE_LICENCE (GPL2_OR_LATER_OR_UBDL)
int parse_string (char *text, char **value)
 Parse string value.
int parse_integer (char *text, unsigned int *value)
 Parse integer value.
int parse_timeout (char *text, unsigned long *value)
 Parse timeout value (in ms)
int parse_netdev (char *text, struct net_device **netdev)
 Parse network device name.
int parse_netdev_configurator (char *text, struct net_device_configurator **configurator)
 Parse network device configurator name.
int parse_menu (char *text, struct menu **menu)
 Parse menu name.
int parse_flag (char *text __unused, int *flag)
 Parse flag.
int parse_key (char *text, unsigned int *key)
 Parse key.
int parse_settings (char *text, struct settings **value)
 Parse settings block name.
int parse_setting (char *text, struct named_setting *setting, get_child_settings_t get_child)
 Parse setting name.
int parse_existing_setting (char *text, struct named_setting *setting)
 Parse existing setting name.
int parse_autovivified_setting (char *text, struct named_setting *setting)
 Parse and autovivify setting name.
int parse_parameters (char *text, struct parameters **params)
 Parse form parameter list name.
void print_usage (struct command_descriptor *cmd, char **argv)
 Print command usage message.
int reparse_options (int argc, char **argv, struct command_descriptor *cmd, void *opts)
 Reparse command-line options.
int parse_options (int argc, char **argv, struct command_descriptor *cmd, void *opts)
 Parse command-line options.

Detailed Description

Command line option parsing.

Definition in file parseopt.c.


Define Documentation

Return status code for "--help" option.

Definition at line 48 of file parseopt.c.

Referenced by reparse_options().

#define EINFO_ECANCELED_NO_OP   __einfo_uniqify ( EINFO_ECANCELED, 0x01, "Nothing to do" )

Definition at line 49 of file parseopt.c.

Definition at line 53 of file parseopt.c.

Referenced by parse_integer().

#define EINFO_EINVAL_INTEGER   __einfo_uniqify ( EINFO_EINVAL, 0x01, "Invalid integer value" )

Definition at line 54 of file parseopt.c.

Definition at line 56 of file parseopt.c.

Referenced by reparse_options().

#define EINFO_EINVAL_UNKNOWN_OPTION   __einfo_uniqify ( EINFO_EINVAL, 0x02, "Unrecognised option" )

Definition at line 57 of file parseopt.c.

Definition at line 59 of file parseopt.c.

Referenced by reparse_options().

#define EINFO_EINVAL_MISSING_ARGUMENT   __einfo_uniqify ( EINFO_EINVAL, 0x03, "Missing argument" )

Definition at line 60 of file parseopt.c.


Function Documentation

FILE_LICENCE ( GPL2_OR_LATER_OR_UBDL  )
int parse_string ( char *  text,
char **  value 
)

Parse string value.

Parameters:
textText
Return values:
valueString value
rcReturn status code

Definition at line 70 of file parseopt.c.

References assert, and NULL.

                                              {

        /* Sanity check */
        assert ( text != NULL );

        /* Parse string */
        *value = text;

        return 0;
}
int parse_integer ( char *  text,
unsigned int *  value 
)

Parse integer value.

Parameters:
textText
Return values:
valueInteger value
rcReturn status code

Definition at line 88 of file parseopt.c.

References assert, EINVAL_INTEGER, NULL, printf(), and strtoul().

Referenced by colour_exec(), cpair_exec(), cpuid_exec(), exit_exec(), inc_exec(), parse_key(), parse_timeout(), pxebs_exec(), and sleep_exec().

                                                      {
        char *endp;

        /* Sanity check */
        assert ( text != NULL );

        /* Parse integer */
        *value = strtoul ( text, &endp, 0 );
        if ( *endp ) {
                printf ( "\"%s\": invalid integer value\n", text );
                return -EINVAL_INTEGER;
        }

        return 0;
}
int parse_timeout ( char *  text,
unsigned long *  value 
)

Parse timeout value (in ms)

Parameters:
textText
Return values:
valueInteger value
rcReturn status code

Definition at line 111 of file parseopt.c.

References parse_integer(), rc, and TICKS_PER_MS.

                                                       {
        unsigned int value_ms;
        int rc;

        /* Parse raw integer value */
        if ( ( rc = parse_integer ( text, &value_ms ) ) != 0 )
                return rc;

        /* Convert to a number of timer ticks */
        *value = ( value_ms * TICKS_PER_MS );

        return 0;
}
int parse_netdev ( char *  text,
struct net_device **  netdev 
)

Parse network device name.

Parameters:
textText
Return values:
netdevNetwork device
rcReturn status code

Definition at line 132 of file parseopt.c.

References assert, ENODEV, find_netdev(), NULL, and printf().

Referenced by ifcommon_exec(), lotest_exec(), pxebs_exec(), vcreate_exec(), and vdestroy_exec().

                                                            {

        /* Sanity check */
        assert ( text != NULL );

        /* Find network device */
        *netdev = find_netdev ( text );
        if ( ! *netdev ) {
                printf ( "\"%s\": no such network device\n", text );
                return -ENODEV;
        }

        return 0;
}
int parse_netdev_configurator ( char *  text,
struct net_device_configurator **  configurator 
)

Parse network device configurator name.

Parameters:
textText
Return values:
configuratorNetwork device configurator
rcReturn status code

Definition at line 154 of file parseopt.c.

References assert, ENOTSUP, find_netdev_configurator(), NULL, and printf().

                                                                               {

        /* Sanity check */
        assert ( text != NULL );

        /* Find network device configurator */
        *configurator = find_netdev_configurator ( text );
        if ( ! *configurator ) {
                printf ( "\"%s\": no such configurator\n", text );
                return -ENOTSUP;
        }

        return 0;
}
int parse_menu ( char *  text,
struct menu **  menu 
)

Parse menu name.

Parameters:
textText
Return values:
menuMenu
rcReturn status code

Definition at line 177 of file parseopt.c.

References ENOENT, find_menu(), and printf().

Referenced by choose_exec(), and item_exec().

                                                  {

        /* Find menu */
        *menu = find_menu ( text );
        if ( ! *menu ) {
                if ( text ) {
                        printf ( "\"%s\": no such menu\n", text );
                } else {
                        printf ( "No default menu\n" );
                }
                return -ENOENT;
        }

        return 0;
}
int parse_flag ( char *text  __unused,
int *  flag 
)

Parse flag.

Parameters:
textText (ignored)
Return values:
flagFlag to set
rcReturn status code

Definition at line 200 of file parseopt.c.

                                                  {

        /* Set flag */
        *flag = 1;

        return 0;
}
int parse_key ( char *  text,
unsigned int *  key 
)

Parse key.

Parameters:
textText
Return values:
keyKey
rcReturn status code

Definition at line 215 of file parseopt.c.

References parse_integer().

                                                {

        /* Interpret single characters as being a literal key character */
        if ( text[0] && ! text[1] ) {
                *key = text[0];
                return 0;
        }

        /* Otherwise, interpret as an integer */
        return parse_integer ( text, key );
}
int parse_settings ( char *  text,
struct settings **  value 
)

Parse settings block name.

Parameters:
textText
Return values:
valueInteger value
rcReturn status code

Definition at line 234 of file parseopt.c.

References assert, EINVAL, find_settings(), NULL, and printf().

Referenced by config_exec().

                                                           {

        /* Sanity check */
        assert ( text != NULL );

        /* Parse scope name */
        *value = find_settings ( text );
        if ( ! *value ) {
                printf ( "\"%s\": no such scope\n", text );
                return -EINVAL;
        }

        return 0;
}
int parse_setting ( char *  text,
struct named_setting setting,
get_child_settings_t  get_child 
)

Parse setting name.

Parameters:
textText
settingNamed setting to fill in
get_childFunction to find or create child settings block
Return values:
rcReturn status code

Note that this function modifies the original text.

Definition at line 259 of file parseopt.c.

References assert, NULL, parse_setting_name(), printf(), rc, named_setting::setting, and named_setting::settings.

Referenced by parse_autovivified_setting(), and parse_existing_setting().

                                                     {
        int rc;

        /* Sanity check */
        assert ( text != NULL );

        /* Parse setting name */
        if ( ( rc = parse_setting_name ( text, get_child, &setting->settings,
                                         &setting->setting ) ) != 0 ) {
                printf ( "\"%s\": invalid setting\n", text );
                return rc;
        }

        return 0;
}
int parse_existing_setting ( char *  text,
struct named_setting setting 
)

Parse existing setting name.

Parameters:
textText
settingNamed setting to fill in
Return values:
rcReturn status code

Note that this function modifies the original text.

Definition at line 285 of file parseopt.c.

References find_child_settings(), and parse_setting().

Referenced by inc_exec(), and show_exec().

                                                                         {

        return parse_setting ( text, setting, find_child_settings );
}
int parse_autovivified_setting ( char *  text,
struct named_setting setting 
)

Parse and autovivify setting name.

Parameters:
textText
settingNamed setting to fill in
Return values:
rcReturn status code

Note that this function modifies the original text.

Definition at line 299 of file parseopt.c.

References autovivify_child_settings(), and parse_setting().

Referenced by choose_exec(), pciscan_exec(), and set_core_exec().

                                                                             {

        return parse_setting ( text, setting, autovivify_child_settings );
}
int parse_parameters ( char *  text,
struct parameters **  params 
)

Parse form parameter list name.

Parameters:
textText
Return values:
paramsParameter list
rcReturn status code

Definition at line 311 of file parseopt.c.

References ENOENT, find_parameters(), and printf().

Referenced by param_exec().

                                                                {

        /* Find parameter list */
        *params = find_parameters ( text );
        if ( ! *params ) {
                if ( text ) {
                        printf ( "\"%s\": no such parameter list\n", text );
                } else {
                        printf ( "No default parameter list\n" );
                }
                return -ENOENT;
        }

        return 0;
}
void print_usage ( struct command_descriptor cmd,
char **  argv 
)

Print command usage message.

Parameters:
cmdCommand descriptor
argvArgument list

Definition at line 333 of file parseopt.c.

References option_descriptor::has_arg, option_descriptor::longopt, command_descriptor::num_options, optional_argument, command_descriptor::options, printf(), PRODUCT_COMMAND_URI, option_descriptor::shortopt, and command_descriptor::usage.

Referenced by reparse_options().

                                                                 {
        struct option_descriptor *option;
        unsigned int i;
        int is_optional;

        printf ( "Usage:\n\n  %s", argv[0] );
        for ( i = 0 ; i < cmd->num_options ; i++ ) {
                option = &cmd->options[i];
                printf ( " [-%c|--%s", option->shortopt, option->longopt );
                if ( option->has_arg ) {
                        is_optional = ( option->has_arg == optional_argument );
                        printf ( " %s<%s>%s", ( is_optional ? "[" : "" ),
                                 option->longopt, ( is_optional ? "]" : "" ) );
                }
                printf ( "]" );
        }
        if ( cmd->usage )
                printf ( " %s", cmd->usage );
        printf ( "\n\nSee " PRODUCT_COMMAND_URI " for further information\n",
                 argv[0] );
}
int reparse_options ( int  argc,
char **  argv,
struct command_descriptor cmd,
void *  opts 
)

Reparse command-line options.

Parameters:
argcArgument count
argvArgument list
cmdCommand descriptor
optsOptions (already initialised with default values)
Return values:
rcReturn status code

Definition at line 364 of file parseopt.c.

References assert, DBGC, ECANCELED_NO_OP, EINVAL_MISSING_ARGUMENT, EINVAL_UNKNOWN_OPTION, ERANGE, getopt_long(), option::has_arg, memset(), option::name, NULL, optarg, optind, optional_argument, print_usage(), rc, option::val, and value.

Referenced by colour_exec(), cpair_exec(), parse_options(), ping_exec(), and sanboot_core_exec().

                                   {
        struct option longopts[ cmd->num_options + 1 /* help */ + 1 /* end */ ];
        char shortopts[ cmd->num_options * 3 /* possible "::" */ + 1 /* "h" */
                        + 1 /* NUL */ ];
        unsigned int shortopt_idx = 0;
        int ( * parse ) ( char *text, void *value );
        void *value;
        unsigned int i;
        unsigned int j;
        unsigned int num_args;
        int c;
        int rc;

        /* Construct long and short option lists for getopt_long() */
        memset ( longopts, 0, sizeof ( longopts ) );
        for ( i = 0 ; i < cmd->num_options ; i++ ) {
                longopts[i].name = cmd->options[i].longopt;
                longopts[i].has_arg = cmd->options[i].has_arg;
                longopts[i].val = cmd->options[i].shortopt;
                shortopts[shortopt_idx++] = cmd->options[i].shortopt;
                assert ( cmd->options[i].has_arg <= optional_argument );
                for ( j = cmd->options[i].has_arg ; j > 0 ; j-- )
                        shortopts[shortopt_idx++] = ':';
        }
        longopts[i].name = "help";
        longopts[i].val = 'h';
        shortopts[shortopt_idx++] = 'h';
        shortopts[shortopt_idx++] = '\0';
        assert ( shortopt_idx <= sizeof ( shortopts ) );
        DBGC ( cmd,  "Command \"%s\" has options \"%s\", %d-%d args, len %d\n",
               argv[0], shortopts, cmd->min_args, cmd->max_args, cmd->len );

        /* Parse options */
        while ( ( c = getopt_long ( argc, argv, shortopts, longopts,
                                    NULL ) ) >= 0 ) {
                switch ( c ) {
                case 'h' :
                        /* Print help */
                        print_usage ( cmd, argv );
                        return -ECANCELED_NO_OP;
                case '?' :
                        /* Print usage message */
                        print_usage ( cmd, argv );
                        return -EINVAL_UNKNOWN_OPTION;
                case ':' :
                        /* Print usage message */
                        print_usage ( cmd, argv );
                        return -EINVAL_MISSING_ARGUMENT;
                default:
                        /* Search for an option to parse */
                        for ( i = 0 ; i < cmd->num_options ; i++ ) {
                                if ( c != cmd->options[i].shortopt )
                                        continue;
                                parse = cmd->options[i].parse;
                                value = ( opts + cmd->options[i].offset );
                                if ( ( rc = parse ( optarg, value ) ) != 0 )
                                        return rc;
                                break;
                        }
                        assert ( i < cmd->num_options );
                }
        }

        /* Check remaining arguments */
        num_args = ( argc - optind );
        if ( ( num_args < cmd->min_args ) || ( num_args > cmd->max_args ) ) {
                print_usage ( cmd, argv );
                return -ERANGE;
        }

        return 0;
}
int parse_options ( int  argc,
char **  argv,
struct command_descriptor cmd,
void *  opts 
)