/* ********************************************************************
* Header File: get_arguments.h
* Author: Bill Hallahan
* Date: September 26, 2013
*
* Copyright (C) 2013 William Hallahan
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without restriction,
* including without limitation the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
******************************************************************* */
#ifndef GET_ARGUMENTS_H
#define GET_ARGUMENTS_H
#include "platform_os.h"
#ifdef __cplusplus
extern "C"
{
#endif /* __cplusplus */
/* The get_arguments function either returns an option
* character or one of these values. */
typedef enum
{
ARG_ERROR_INVALID_SWITCH = -2,
ARG_ERROR_MISSING_SWITCH_ARGUMENT = -1,
ARG_NO_MORE_ARGUMENTS = 0,
ARG_POSITIONAL_ARGUMENT = 0x7FFFFFFF
} ArgOptionChar_t;
/* Used to set whether an option requires a parameter. */
typedef enum
{
OPTION_NO_PARAMETER,
OPTION_REQUIRES_PARAMETER
} ArgOptionParameter_t;
/* The option structure.
* Element c stores the short option character, i.e. "b" for "-b".
* name is the long option name string, "build" for "--build".
* requires_params is set to one of the ArgOptionParameter_t
* enum values to indicate whether the option requires a parameter. */
typedef struct
{
int c;
TCHAR * long_name;
ArgOptionParameter_t requires_param;
} ArgOption_t;
/* ********************************************************************
* Function: get_arguments
*
* Abstract:
*
* The get_arguments function was written to provide argument
* parsing code for multiple platforms. Also, the code can
* be used under the terms of the MIT license.
*
* The get_arguments function allows both short and long
* optional switches, and will work with the ASCII, UTF-8, and
* Unicode character sets.
*
* Both single character and long optional argument switch
* named are allowed.
*
* Optional arguments and positional arguments can be interspersed.
*
* The benefit of allowing interspersed optional and positional
* arguments comes at the cost of requiring that an optional argument
* either does, or does not, take an additional parameter, but not both.
*
* Also, optional argument names cannot start with a digit
* character. This simplified parsing as a dash followed by
* a digit character could also be the start of a numeric
* positional argument.
*
* Input:
*
* The first two arguments are passed into the 'main' function of
* a C or C++ console program.
*
* argc - The number of arguments.
*
* argv - An array of pointers to argument strings.
*
* argument_option_array_ptr - A pointer to an array of ArgOption_t
* structures that specifies that attributes
* of each optional argument.
*
* An example declaration for the array might be:
*
* static const ArgOption_t argument_option_array[] =
* {
* { 'x', NULL, OPTION_NO_PARAMETER, },
* { 'f', NULL, OPTION_REQUIRES_PARAMETER, },
* { 'b', "build", OPTION_REQUIRES_PARAMETER, },
* { 'h', "help", OPTION_NO_PARAMETER, },
* { 0, NULL, OPTION_NO_PARAMETER }
* };
*
* This would allow optional arguments of the form:
*
* -x
* -f <somestring>
* -b <somestring>
* --build <somestring>
* -h
* --help
*
* A string must be supplied after the -s parameter
* because OPTION_REQUIRES_PARAMETER is used.
*
* The final line must always be supplied as written
* to terminate the data.
*
* Either a short argument name, a long
* argument name, or both must be specified.
* If only a long name is specified, the first
* field of the ArgOption_t structure must be
* set to an out-of-band integer value, which
* for either ASCII or Unicode character sets
* can be any value above 0x011FFFF.
*
*
* arg_index_ptr A pointer to an 'int' value that is used
* to index into the argv[] array. The value
* pointed to by arg_index_ptr specifies either
* the index of a positional argument or the
* index of the required parameter for an
* optional argument that has the
* OPTION_REQUIRES_PARAMETER attribute.
*
* Returns:
*
* An integer value that is either the option character for an
* optional argument, which is the first field in OptionsArg_t
* structure that matches the optional argument passed on the
* command line, or, one of the following values.
*
* ARG_POSITIONAL_ARGUMENT - Specified that argument in the argv
* array, indexed by the index value
* pointed to by arg_index_ptr, is a
* positional argument.
*
* ARG_NO_MORE_ARGUMENTS - Specifies that there are no more
* arguments to parse.
*
* ARG_ERROR_INVALID_SWITCH - Invalid switch specified on the command
* line.
*
* ARG_ERROR_MISSING_SWITCH_ARGUMENT - A dash character for an
* optional argument was found
* but is missing required
* characters following the dash.
*
* Any returned character value, represented as an integer, and
* the value of ARG_POSITIONAL_ARGUMENT, are always greater than
* zero. ARG_NO_MORE_ARGUMENTS equals zero, and the error return
* values are negative numbers, so parsing should be done until
* the return value of this function is not greater than
* ARG_NO_MORE_ARGUMENTS, or zero.
*
******************************************************************* */
int get_arguments(int argc,
TCHAR *argv[],
const ArgOption_t * argument_option_array_ptr,
int * arg_index_ptr);
#ifdef __cplusplus
}
#endif /* __cplusplus */
#endif /* GET_ARGUMENTS_H */