/*
 *
 *    Copyright (c) 2017 Nest Labs, Inc.
 *    All rights reserved.
 *
 *    Licensed under the Apache License, Version 2.0 (the "License");
 *    you may not use this file except in compliance with the License.
 *    You may obtain a copy of the License at
 *
 *        http://www.apache.org/licenses/LICENSE-2.0
 *
 *    Unless required by applicable law or agreed to in writing, software
 *    distributed under the License is distributed on an "AS IS" BASIS,
 *    WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 *    See the License for the specific language governing permissions and
 *    limitations under the License.
 */

/**
 *    @file
 *      Support functions for parsing command-line arguments.
 *
 */

#ifndef __STDC_LIMIT_MACROS
#define __STDC_LIMIT_MACROS
#endif
#ifndef __STDC_FORMAT_MACROS
#define __STDC_FORMAT_MACROS
#endif

#include <stdint.h>
#include <inttypes.h>
#include <limits.h>
#include <ctype.h>
#include <string.h>
#include <errno.h>

#include "nlargparser.hpp"

#if WEAVE_CONFIG_ENABLE_ARG_PARSER

#include <getopt.h>

namespace nl {
namespace ArgParser {

using namespace nl::Inet;
using namespace nl::Weave;

static char *MakeShortOptions(OptionSet **optSets);
static struct option *MakeLongOptions(OptionSet **optSets);
static int32_t SplitArgs(char *argStr, char **& argList, char *initialArg = NULL);
static bool GetNextArg(char *& parsePoint);
static size_t CountOptionSets(OptionSet *optSets[]);
static size_t CountAllOptions(OptionSet *optSets[]);
static void FindOptionByIndex(OptionSet **optSets, int optIndex, OptionSet *& optSet, OptionDef *& optDef);
static void FindOptionById(OptionSet **optSets, int optId, OptionSet *& optSet, OptionDef *& optDef);
static const char **MakeUniqueHelpGroupNamesList(OptionSet *optSets[]);
static void PutStringWithNewLine(FILE *s, const char *str);
static void PutStringWithBlankLine(FILE *s, const char *str);
#if WEAVE_CONFIG_ENABLE_ARG_PARSER_SANTIY_CHECK
static bool SanityCheckOptions(OptionSet *optSets[]);
static bool HelpTextContainsLongOption(const char *optName, const char *helpText);
static bool HelpTextContainsShortOption(char optChar, const char *helpText);
#endif // WEAVE_CONFIG_ENABLE_ARG_PARSER_SANTIY_CHECK

static inline bool IsShortOptionChar(int ch)
{
    return isascii(ch) && isgraph(ch);
}

/**
 * @brief
 * The list of OptionSets passed to the currently active ParseArgs() call.
 *
 * @details
 * This value will be NULL when no call to ParseArgs() is in progress.
 */
OptionSet **gActiveOptionSets = NULL;


/**
 * @brief
 * Pointer to function used to print errors that occur during argument parsing.
 *
 * @details
 * Applications should call PrintArgError() to report errors in their option and
 * non-option argument handling functions, rather than printing directly to
 * stdout/stderr.
 *
 * Defaults to a pointer to the `DefaultPrintArgError()` function.
 */
void (*PrintArgError)(const char *msg, ...) = DefaultPrintArgError;


/**
 * @fn bool ParseArgs(const char *progName, int argc, char *argv[], OptionSet *optSets[], NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
 *
 * @brief
 * Parse a set of command line-style arguments, calling handling functions to process each
 * option and non-option argument.
 *
 * @param[in]  progName             The name of the program or context in which the arguments are
 *                                  being parsed.  This string will be used to prefix error
 *                                  messages and warnings.
 * @param[in]  argc                 The number of arguments to be parsed, plus 1.
 * @param[in]  argv                 An array of argument strings to be parsed.  The array length must
 * 									be 1 greater than the value specified for argc, and argv[argc] must
 * 									be set to NULL.  Argument parsing begins with the *second* array
 * 									element (argv[1]); element 0 is ignored.
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that define the legal
 *                                  options.  The supplied list must be terminated with a NULL.
 * @param[in]  nonOptArgHandler     A pointer to a function that will be called once option parsing
 *                                  is complete with any remaining non-option arguments .  The function
 *                                  is called regardless of whether any arguments remain.  If a NULL
 *                                  is passed `ParseArgs()` will report an error if any non-option
 *                                  arguments are present.
 * @param[in]  ignoreUnknown        If true, silently ignore any unrecognized options.
 *
 * @return                          `true` if all options and non-option arguments were parsed
 *                                  successfully; `false` if an option was unrecognized or if one of
 *                                  the handler functions failed (i.e. returned false).
 *
 *
 * @details
 * ParseArgs() takes a list of arguments (`argv`) and parses them according to a set of supplied
 * option definitions.  The function supports both long (--opt) and short (-o) options and implements
 * the same option syntax as the GNU getopt_long(3) function.
 *
 * Option definitions are passed to ParseArgs() as an array of OptionSet structures (`optSets`).
 * Each OptionSet contains an array of option definitions and a handler function. ParseArgs()
 * processes option arguments in the given order, calling the respective handler function for
 * each recognized option.  Once all options have been parsed, a separate non-option handler
 * function (`nonOptArgHandler`) is called once to process any remaining arguments.
 *
 *
 * ## OPTION SETS
 *
 * An OptionSet contains a set of option definitions along with a pointer to a handler function
 * that will be called when one of the associated options is encountered.  Option sets also
 * contain help text describing the syntax and purpose of each option (see OPTION HELP below).
 * Option sets are designed to allow the creation of re-usable collections of related options.
 * This simplifies the effort needed to maintain multiple applications that accept similar options
 * (e.g. test applications).
 *
 * There are two patterns for defining OptionSets--one can either initialize an instance of the
 * OptionSet struct itself, e.g. as a static global, or subclass OptionSetBase and provide a
 * constructor.  The latter uses a pure virtual `HandleOption()` function to delegate option
 * handling to the subclass.
 *
 * Lists of OptionSets are passed to the ParseArgs() function as a NULL-terminated array of pointers.
 * E.g.:
 *
 *     static OptionSet gToolOptions =
 *     {
 *         HandleOption,        // handler function
 *         gToolOptionDefs,  // array of option definitions
 *         "GENERAL OPTIONS",   // help group
 *         gToolOptionHelp   // option help text
 *     };
 *
 *     static OptionSet *gOptionSets[] =
 *     {
 *         &gToolOptions,
 *         &gNetworkOptions,
 *         &gTestingOptions,
 *         &gHelpOptions,
 *         NULL
 *     };
 *
 *     int main(int argc, char *argv[])
 *     {
 *         if (!ParseArgs("test-app", argc, argv, gOptionSets))
 *         {
 *             ...
 *         }
 *     }
 *
 *
 * ## OPTION DEFINITIONS
 *
 * Options are defined using the `OptionDef` structure. Option definitions are organized as an array
 * of OptionDef elements, where each element contains: the name of the option, a integer id that is
 * used to identify the option, and whether the option expects/allows an argument.  The end of the
 * option array is signaled by a NULL Name field.  E.g.:
 *
 *     enum
 *     {
 *         kOpt_Listen = 1000,
 *         kOpt_Length,
 *         kOpt_Count,
 *     };
 *
 *     static OptionDef gToolOptionDefs[] =
 *     {
 *         // NAME         REQUIRES/ALLOWS ARG?  ID/SHORT OPTION CHAR
 *         // ============================================================
 *         {  "listen",    kNoArgument,          kOpt_Listen     },
 *         {  "length",    kArgumentRequired,    kOpt_Length     },
 *         {  "count",     kArgumentRequired,    kOpt_Count      },
 *         {  "num",       kArgumentRequired,    kOpt_Count      }, // alias for --count
 *         {  "debug",     kArgumentOptional,    'd'             },
 *         {  "help",      kNoArgument,          'h'             },
 *         {  NULL }
 *     };
 *
 *
 * ## OPTION IDS
 *
 * Option ids identify options to the code that handles them (the OptionHandler function). Option ids
 * are relative to the OptionSet in which they appear, and thus may be reused across different
 * OptionSets (however see SHORT OPTIONS below).  Common convention is to start numbering option ids
 * at 1000, however any number > 128 can be used.  Alias options can be created by using the same
 * option id with different option names.
 *
 *
 * ## SHORT OPTIONS
 *
 * Unlike getopt_long(3), ParseArgs() does not take a separate string specifying the list of short
 * option characters.  Rather, any option whose id value falls in the range of graphical ASCII
 * characters will allow that character to be used as a short option.
 *
 * ParseArgs() requires that short option characters be unique across *all* OptionSets.  Because of
 * this, the use of short options is discouraged for any  OptionSets that are shared across programs
 * due to the significant chance for collisions.  Short options characters may be reused within a
 * single OptionSet to allow for the creation of alias long option names.
 *
 *
 * ## OPTION HELP
 *
 * Each OptionSet contains an `OptionHelp` string that describes the purpose and syntax of the
 * associated options.  These strings are used by the `PrintOptionHelp()` function to generate
 * option usage information.
 *
 * By convention, option help strings consist of a syntax example following by a textual
 * description of the option.  If the option has a short version, or an alias name, it is given
 * before primary long name.  For consistency, syntax lines are indented with 2 spaces, while
 * description lines are indented with 7 spaces.  A single blank line follows each option
 * description, including the last one.
 *
 * E.g.:
 *
 *     static const char *const gToolOptionHelp =
 *         "  --listen\n"
 *         "       Listen and respond to requests sent from another node.\n"
 *         "\n"
 *         "  --length <num>\n"
 *         "       Send requests with the specified number of bytes in the payload.\n"
 *         "\n"
 *         "  --num, --count <num>\n"
 *         "       Send the specified number of requests and exit.\n"
 *         "\n"
 *         "  -d, --debug [<level>]\n"
 *         "       Set debug logging to the given level. (Default: 1)\n"
 *         "\n"
 *         "  -h, --help\n"
 *         "       Print help information.\n"
 *         "\n";
 *
 *
 * ## OPTION HELP GROUPS
 *
 * OptionSets contain a `HelpGroupName` string which is used to group options together in the
 * help output.  The `PrintOptionHelp()` function uses the HelpGroupName as a section title in
 * the generated usage output.  If multiple OptionSets have the same HelpGroupName,
 * PrintOptionHelp() will print the option help for the different OptionSets together under
 * a common section title.
 *
 */
bool ParseArgs(const char *progName, int argc, char *argv[], OptionSet *optSets[], NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
{
    bool res = false;
    char optName[64];
    char *optArg;
    char *shortOpts = NULL;
    struct option *longOpts = NULL;
    OptionSet *curOptSet;
    OptionDef *curOpt;
    bool handlerRes;

    // The getopt() functions do not support recursion, so exit immediately with an
    // error if called recursively.
    if (gActiveOptionSets != NULL)
    {
        PrintArgError("INTERNAL ERROR: ParseArgs() called recursively\n", progName);
        return false;
    }

    // The C standard mandates that argv[argc] == NULL and certain versions of getopt() require this
    // to function properly.  So fail if this is not true.
    if (argv[argc] != NULL)
    {
        PrintArgError("INTERNAL ERROR: argv[argc] != NULL\n", progName);
        return false;
    }

    // Set gActiveOptionSets to the current option set list.
    gActiveOptionSets = optSets;

#if WEAVE_CONFIG_ENABLE_ARG_PARSER_SANTIY_CHECK
    if (!SanityCheckOptions(optSets))
        goto done;
#endif

    // Generate a short options string in the format expected by getopt_long().
    shortOpts = MakeShortOptions(optSets);
    if (shortOpts == NULL)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        goto done;
    }

    // Generate a list of long option structures in the format expected by getopt_long().
    longOpts = MakeLongOptions(optSets);
    if (longOpts == NULL)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        goto done;
    }

    // Force getopt() to reset its internal state.
    optind = 0;

    // Process any option arguments...
    while (true)
    {
        int id;
        int optIndex = -1;

        // Attempt to match the current option argument (argv[optind]) against the defined long and short options.
        optarg = NULL;
        optopt = 0;
        id = getopt_long(argc, argv, shortOpts, longOpts, &optIndex);

        // Stop if there are no more options.
        if (id == -1)
            break;

        // If the current option is unrecognized, fail with an error message unless ignoreUnknown == true.
        if (id == '?')
        {
            if (ignoreUnknown)
                continue;
            if (optopt != 0)
                PrintArgError("%s: Unknown option: -%c\n", progName, optopt);
            else
                PrintArgError("%s: Unknown option: %s\n", progName, argv[optind-1]);
            goto done;
        }

        // If the option was recognized, but it is lacking an argument, fail with
        // an error message.
        if (id == ':')
        {
            // NOTE: with the way getopt_long() works, it is impossible to tell whether the option that
            // was missing an argument was a long option or a short option.
            PrintArgError("%s: Missing argument for %s option\n", progName, argv[optind - 1]);
            goto done;
        }

        // If a long option was matched...
        if (optIndex != -1)
        {

            // Locate the option set and definition using the index value returned by getopt_long().
            FindOptionByIndex(optSets, optIndex, curOptSet, curOpt);

            // Form a string containing the name of the option as it appears on the command line.
            snprintf(optName, sizeof(optName), "--%s", curOpt->Name);
        }

        // Otherwise a short option was matched...
        else
        {
            // Locate the option set and definition using the option id.
            FindOptionById(optSets, id, curOptSet, curOpt);

            // Form a string containing the name of the short option as it would appears on the
            // command line if given by itself.
            snprintf(optName, sizeof(optName), "-%c", id);
        }

        // Prevent handlers from inadvertently using the getopt global optarg.
        optArg = optarg;
        optarg = NULL;

        // Call the option handler function defined for the matching option set.
        // Exit immediately if the option handler failed.
        handlerRes = curOptSet->OptionHandler(progName, curOptSet, id, optName, optArg);
        if (!handlerRes)
            goto done;
    }

    // If supplied, call the non-option argument handler with the remaining arguments (if any).
    if (nonOptArgHandler != NULL)
    {
        if (!nonOptArgHandler(progName, argc - optind, argv + optind))
            goto done;
    }

    // otherwise, if there are additional arguments, fail with an error.
    else if (optind < argc)
    {
        PrintArgError("%s: Unexpected argument: %s\n", progName, argv[optind]);
        goto done;
    }

    res = true;

done:

    if (shortOpts != NULL)
        free(shortOpts);
    if (longOpts != NULL)
        free(longOpts);

    gActiveOptionSets = NULL;

    return res;
}

bool ParseArgs(const char *progName, int argc, char *argv[], OptionSet *optSets[], NonOptionArgHandlerFunct nonOptArgHandler)
{
    return ParseArgs(progName, argc, argv, optSets, nonOptArgHandler, false);
}

bool ParseArgs(const char *progName, int argc, char *argv[], OptionSet *optSets[])
{
    return ParseArgs(progName, argc, argv, optSets, NULL, false);
}


/**
 * @brief
 * Parse a set of arguments from a given string.
 *
 * @param[in]  progName             The name of the program or context in which the arguments are
 *                                  being parsed.  This string will be used to prefix error
 *                                  messages and warnings.
 * @param[in]  argStr               A string containing options and arguments to be parsed.
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that define the legal
 *                                  options.  The supplied list must be terminated with a NULL.
 * @param[in]  nonOptArgHandler     A pointer to a function that will be called once option parsing
 *                                  is complete with any remaining non-option arguments .  The function
 *                                  is called regardless of whether any arguments remain.  If a NULL
 *                                  is passed `ParseArgs()` will report an error if any non-option
 *                                  arguments are present.
 * @param[in]  ignoreUnknown        If true, silently ignore any unrecognized options.
 *
 * @return                          `true` if all options and non-option arguments were parsed
 *                                  successfully; `false` if an option was unrecognized, if one of
 *                                  the handler functions failed (i.e. returned false) or if an
 *                                  internal error occurred.
 *
 * @details
 * ParseArgsFromString() splits a given string (`argStr`) into a set of arguments and parses the
 * arguments using the ParseArgs() function.
 *
 * The syntax of the input strings is similar to unix shell command syntax, but with a simplified
 * quoting scheme.  Specifically:
 *
 * - Arguments are delimited by whitespace, unless the whitespace is quoted or escaped.
 *
 * - A backslash escapes the following character, causing it to be treated as a normal character.
 * The backslash itself is stripped.
 *
 * - Single or double quotes begin/end quoted substrings.  Within a substring, the only special
 * characters are backslash, which escapes the next character, and the corresponding end quote.
 * The begin/end quote characters are stripped.
 *
 * E.g.:
 *
 *     --listen --count 10 --sw-version '1.0 (DEVELOPMENT)' "--hostname=nest.com"
 *
 */
bool ParseArgsFromString(const char *progName, const char *argStr, OptionSet *optSets[], NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
{
    char *argStrCopy = NULL;
    char **argv = NULL;
    int argc;
    bool res;

    argStrCopy = strdup(argStr);
    if (argStrCopy == NULL)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        return false;
    }

    argc = SplitArgs(argStrCopy, argv, (char *)progName);
    if (argc < 0)
    {
        PrintArgError("%s: Memory allocation failure\n", progName);
        free(argStrCopy);
        return false;
    }

    res = ParseArgs(progName, argc, argv, optSets, nonOptArgHandler, ignoreUnknown);

    free(argStrCopy);
    free(argv);

    return res;
}

bool ParseArgsFromString(const char *progName, const char *argStr, OptionSet *optSets[], NonOptionArgHandlerFunct nonOptArgHandler)
{
    return ParseArgsFromString(progName, argStr, optSets, nonOptArgHandler, false);
}

bool ParseArgsFromString(const char *progName, const char *argStr, OptionSet *optSets[])
{
    return ParseArgsFromString(progName, argStr, optSets, NULL, false);
}


/**
 * @brief
 * Parse a set of arguments from a named environment variable
 *
 * @param[in]  progName             The name of the program or context in which the arguments are
 *                                  being parsed.  This string will be used to prefix error
 *                                  messages and warnings.
 * @param[in]  varName              The name of the environment variable.
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that define the legal
 *                                  options.  The supplied list must be terminated with a NULL.
 * @param[in]  nonOptArgHandler     A pointer to a function that will be called once option parsing
 *                                  is complete with any remaining non-option arguments .  The function
 *                                  is called regardless of whether any arguments remain.  If a NULL
 *                                  is passed `ParseArgs()` will report an error if any non-option
 *                                  arguments are present.
 * @param[in]  ignoreUnknown        If true, silently ignore any unrecognized options.
 *
 * @return                          `true` if all options and non-option arguments were parsed
 *                                  successfully, or if the specified environment variable is not set;
 *                                  `false` if an option was unrecognized, if one of the handler
 *                                  functions failed (i.e. returned false) or if an internal error
 *                                  occurred.
 *
 * @details
 * ParseArgsFromEnvVar() reads a named environment variable and passes the value to `ParseArgsFromString()`
 * for parsing.  If the environment variable is not set, the function does nothing.
 */

bool ParseArgsFromEnvVar(const char *progName, const char *varName, OptionSet *optSets[], NonOptionArgHandlerFunct nonOptArgHandler, bool ignoreUnknown)
{
    const char *argStr = getenv(varName);
    if (argStr == NULL)
        return true;
    return ParseArgsFromString(progName, argStr, optSets, nonOptArgHandler, ignoreUnknown);
}

bool ParseArgsFromEnvVar(const char *progName, const char *varName, OptionSet *optSets[])
{
    return ParseArgsFromEnvVar(progName, varName, optSets, NULL, false);
}

bool ParseArgsFromEnvVar(const char *progName, const char *varName, OptionSet *optSets[], NonOptionArgHandlerFunct nonOptArgHandler)
{
    return ParseArgsFromEnvVar(progName, varName, optSets, nonOptArgHandler, false);
}

/**
 * @brief
 * Print the help text for a specified list of options to a stream.
 *
 * @param[in]  optSets              A list of pointers to `OptionSet` structures that contain the
 *                                  help text to print.
 * @param[in]  s                    The FILE stream to which the help text should be printed.
 *
 */
void PrintOptionHelp(OptionSet *optSets[], FILE *s)
{
    // Get a list of the unique help group names for the given option sets.
    const char **helpGroupNames = MakeUniqueHelpGroupNamesList(optSets);
    if (helpGroupNames == NULL)
    {
        PrintArgError("Memory allocation failure\n");
        return;
    }

    // For each help group...
    for (size_t nameIndex = 0; helpGroupNames[nameIndex] != NULL; nameIndex++)
    {
        // Print the group name.
        PutStringWithBlankLine(s, helpGroupNames[nameIndex]);

        // Print the option help text for all options that have the same group name.
        for (size_t optSetIndex = 0; optSets[optSetIndex] != NULL; optSetIndex++)
            if (strcasecmp(helpGroupNames[nameIndex], optSets[optSetIndex]->HelpGroupName) == 0)
            {
                PutStringWithBlankLine(s, optSets[optSetIndex]->OptionHelp);
            }
    }

    free(helpGroupNames);
}

/**
 * @brief
 * Print an error message associated with argument parsing.
 *
 * @param[in]  msg   The message to be printed.
 *
 * @details
 * Default function used to print error messages that arise due to the parsing
 * of arguments.
 *
 * Applications should call through the PrintArgError function pointer, rather
 * than calling this function directly.
 */
void DefaultPrintArgError(const char *msg, ...)
{
    va_list ap;

    va_start(ap, msg);
    vfprintf(stderr, msg, ap);
    va_end(ap);
}

/**
 * Parse a string as a boolean value.
 *
 * This function accepts the following input values (case-insensitive):
 * "true", "yes", "t", "y", "1", "false", "no", "f", "n", "0".
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the value to parse.
 * @param[out] output A reference to storage for a bool to which the parsed
 *                    value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseBoolean(const char *str, bool& output)
{
    if (strcasecmp(str, "true") == 0 ||
        strcasecmp(str, "yes") == 0 ||
        ((str[0] == '1' || str[0] == 't' || str[0] == 'T' || str[0] == 'y' || str[0] == 'Y') && str[1] == 0))
    {
        output = true;
        return true;
    }

    if (strcasecmp(str, "false") == 0 ||
        strcasecmp(str, "no") == 0 ||
        ((str[0] == '0' || str[0] == 'f' || str[0] == 'F' || str[0] == 'n' || str[0] == 'N') && str[1] == 0))
    {
        output = false;
        return true;
    }

    return false;
}

/**
 * Parse and attempt to convert a string to a 64-bit unsigned integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 64-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, uint64_t& output, int base)
{
    char *parseEnd;

    errno = 0;
    output = strtoull(str, &parseEnd, base);

    return parseEnd > str && *parseEnd == 0 && (output != ULLONG_MAX || errno == 0);
}

/**
 * Parse and attempt to convert a string to a 32-bit unsigned integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, uint32_t& output, int base)
{
    char *parseEnd;
    unsigned long v;

    errno = 0;
    v = strtoul(str, &parseEnd, base);
    output = v;

    return parseEnd > str && *parseEnd == 0 && (v != ULONG_MAX || errno == 0);
}

/**
 * Parse and attempt to convert a string to a 32-bit signed integer,
 * applying the appropriate interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit signed integer
 *                    to which the parsed value will be stored on success.
 * @param[in]  base   The base according to which the string should be
 *                    interpreted and parsed. If 0 or 16, the string may
 *                    be hexadecimal and prefixed with "0x". Otherwise, a 0
 *                    is implied as 10 unless a leading 0 is encountered in
 *                    which 8 is implied.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, int32_t& output, int base)
{
    char *parseEnd;
    long v;

    errno = 0;
    v = strtol(str, &parseEnd, base);
    output = v;

    return parseEnd > str && *parseEnd == 0 && ((v != LONG_MIN && v != LONG_MAX) || errno == 0);
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 64-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 64-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, uint64_t& output)
{
    const int base = 10;

    return ParseInt(str, output, base);
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 32-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, uint32_t& output)
{
    const int base = 10;

    return ParseInt(str, output, base);
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 32-bit signed integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 32-bit signed integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, int32_t& output)
{
    const int base = 10;

    return ParseInt(str, output, base);
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 16-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 16-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, uint16_t& output)
{
    const int base = 10;
    uint32_t output32 = 0;

    if ((ParseInt(str, output32, base)) && (output32 <= USHRT_MAX))
    {
        output = ((1 << 16) - 1) & output32;
        return true;
    }

    return false;
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 16-bit signed integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 16-bit signed integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, int16_t& output)
{
    const int base = 10;
    int32_t output32 = 0;

    if ((ParseInt(str, output32, base)) && (output32 <= SHRT_MAX))
    {
        output = ((1 << 16) - 1) & output32;
        return true;
    }

    return false;
}

/**
 * Parse and attempt to convert a string interpreted as a decimal
 * value to a 8-bit unsigned integer, applying the appropriate
 * interpretation based on the base parameter.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string representing
 *                    the integer to parse.
 * @param[out] output A reference to storage for a 8-bit unsigned integer
 *                    to which the parsed value will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseInt(const char *str, uint8_t& output)
{
    const int base = 10;
    uint32_t output32 = 0;

    if ((ParseInt(str, output32, base)) && (output32 <= UCHAR_MAX))
    {
        output = ((1 << 8) - 1) & output32;
        return true;
    }

    return false;
}

/**
 * Parse an IP address in text form.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string containing
 *                    the address to parse.
 * @param[out] output A reference to an IPAddress object in which the parsed
 *                    value will be stored on success.
 *
 * @return true if the value was successfully parsed; false if not.
 */
bool ParseIPAddress(const char *str, IPAddress& output)
{
    return IPAddress::FromString(str, output);
}

/**
 * Parse a Weave node id in text form.
 *
 * @param[in]  str    A pointer to a NULL-terminated C string containing
 *                    the node id to parse.
 * @param[out] output A reference to an uint64_t lvalue in which the parsed
 *                    value will be stored on success.
 *
 * @return true if the value was successfully parsed; false if not.
 *
 * @details
 * The ParseNodeId() function accepts either a 64-bit node id given in hex
 * format (with or without a leading '0x'), or the words 'any' or 'all' which
 * are interpreted as meaning the Any node id (0xFFFFFFFFFFFFFFFF).
 */
bool ParseNodeId(const char *str, uint64_t& nodeId)
{
    char *parseEnd;

    if (strcasecmp(str, "any") == 0 || strcasecmp(str, "all") == 0)
    {
        nodeId = kAnyNodeId;
        return true;
    }

    errno = 0;
    nodeId = strtoull(str, &parseEnd, 16);
    return parseEnd > str && *parseEnd == 0 && (nodeId != ULLONG_MAX || errno == 0);
}

/**
 * Parse a Weave fabric id in text form.
 *
 * @param[in]  str              A pointer to a NULL-terminated C string containing
 *                              the fabric id to parse.
 * @param[out] output           A reference to an uint64_t lvalue in which the
 *                              parsed value will be stored on success.
 * @param[in]  allowReserved    If true, allow the parsing of fabric ids in the
 *                              reserved range.
 *
 * @return true if the value was successfully parsed; false if not.
 *
 * @details
 * The ParseFabricId() function accepts a 64-bit fabric id given in hex format,
 * with or without a leading '0x'.
 */
bool ParseFabricId(const char *str, uint64_t& fabricId, bool allowReserved)
{
    char *parseEnd;

    errno = 0;
    fabricId = strtoull(str, &parseEnd, 16);
    return parseEnd > str && *parseEnd == 0 && (fabricId != ULLONG_MAX || errno == 0)
        && (allowReserved || fabricId < kReservedFabricIdStart);
}

/**
 * Parse and attempt to convert a string to a 16-bit unsigned subnet
 * ID, interpretting the string as hexadecimal.
 *
 * @param[in]    str       A pointer to a NULL-terminated C string
 *                         representing the subnet ID, formatted as a
 *                         hexadecimal, to parse.
 * @param[inout] subnetId  A reference to storage for a 16-bit unsigned
 *                         integer to which the parsed subnet ID value
 *                         will be stored on success.
 *
 * @return true on success; otherwise, false on failure.
 */
bool ParseSubnetId(const char *str, uint16_t &subnetId)
{
    char *        parseEnd;
    unsigned long temp;
    bool          valid;

    // Reset errno per the strtoul manual page.

    errno = 0;

    // Attempt to parse the subnet ID as a hexadecimal number.

    temp = strtoul(str, &parseEnd, 16);

    // Determine if the parse and conversion were valid.

    valid = (parseEnd > str                    &&  // Parsed some valid hexadecimal digits
             *parseEnd == 0                    &&  // Encountered no invalid hexadecimal digits
             (temp != ULONG_MAX || errno == 0) &&  // No overflow (ERANGE) or invalid base (EINVAL) errors
             temp <= USHRT_MAX);                   // Parsed value is valid for the domain (subnet ID)

    if (valid) {
        subnetId = static_cast<uint16_t>(temp);
    }

    return valid;
}

/**
 * Parse a string of bytes given in hex form.
 *
 * @param[in]  hexStr           A pointer to the string to parse.
 * @param[in]  strLen           The number of characters in hexStr to parse.
 * @param[in]  outBuf           A pointer to a buffer into which the parse bytes will
 *                              be stored.
 * @param[in]  outBufSize       The size of the buffer pointed at by `outBuf`.
 * @param[out] outDataLen       A reference to an integer that will receive the total
 *                              number of bytes parsed.  In the event outBuf is not
 *                              big enough to hold the given number of bytes, `outDataLen`
 *                              will be set to UINT32_MAX.
 *
 * @return true if the value was successfully parsed; false if the input data is malformed,
 * or if `outBuf` is too small.
 *
 * @details
 * ParseHexString() expects the input to be in the form of pairs of hex digits (upper or lower case).
 * Hex pairs can optionally be separated by any of the following characters: colon, semicolon, comma, period or dash.
 * Additionally, whitespace characters anywhere in the input string are ignored.
 */
bool ParseHexString(const char *hexStr, uint32_t strLen, uint8_t *outBuf, uint32_t outBufSize, uint32_t& outDataLen)
{
    bool isFirstNibble = true;
    uint8_t firstNibbleVal;
    const char *p = hexStr;
    uint32_t dataLen = 0;

    outDataLen = 0;

    for (; strLen > 0; p++, strLen--)
    {
        char c = *p;
        uint8_t nibbleVal;

        if (c == 0)
            break;
        if (c >= '0' && c <= '9')
            nibbleVal = c - '0';
        else if (c >= 'a' && c <= 'f')
            nibbleVal = 10 + (c - 'a');
        else if (c >= 'A' && c <= 'F')
            nibbleVal = 10 + (c - 'A');
        else if (isspace(c))
            continue;
        else if (isFirstNibble && (c == ':' || c == ';' || c == ',' || c == '.' || c == '-'))
            continue;
        else
        {
            outDataLen = p - hexStr;
            return false;
        }

        if (isFirstNibble)
        {
            firstNibbleVal = nibbleVal;
            isFirstNibble = false;
        }
        else
        {
            if (outBufSize == 0)
            {
                outDataLen = UINT32_MAX;
                return false;
            }

            *outBuf = firstNibbleVal << 4 | nibbleVal;

            outBuf++;
            outBufSize--;
            dataLen++;

            isFirstNibble = true;
        }
    }

    if (!isFirstNibble)
    {
        outDataLen = p - hexStr;
        return false;
    }

    outDataLen = dataLen;

    return true;
}

// ===== HelpOptions Methods =====

HelpOptions::HelpOptions(const char *appName, const char *appUsage, const char *appVersion)
    : HelpOptions(appName, appUsage, appVersion, NULL)
{
}

HelpOptions::HelpOptions(const char *appName, const char *appUsage, const char *appVersion, const char *appDesc)
{
    static OptionDef optionDefs[] =
    {
        { "help",      kNoArgument, 'h' },
        { "version",   kNoArgument, 'v' },
        { }
    };
    OptionDefs = optionDefs;

    HelpGroupName = "HELP OPTIONS";

    OptionHelp =
        "  -h, --help\n"
        "       Print this output and then exit.\n"
        "\n"
        "  -v, --version\n"
        "       Print the version and then exit.\n"
        "\n";

    AppName = appName;
    AppUsage = appUsage;
    AppVersion = appVersion;
    AppDesc = appDesc;
}

/**
 * Print a short description of the command's usage followed by instructions on how to get more help.
 */
void HelpOptions::PrintBriefUsage(FILE *s)
{
    PutStringWithNewLine(s, AppUsage);
    fprintf(s, "Try `%s --help' for more information.\n", AppName);
}

/**
 * Print the full usage information, including information on all available options.
 */
void HelpOptions::PrintLongUsage(OptionSet **optSets, FILE *s)
{
    PutStringWithBlankLine(s, AppUsage);
    if (AppDesc != NULL)
    {
        PutStringWithBlankLine(s, AppDesc);
    }
    PrintOptionHelp(optSets, s);
}

void HelpOptions::PrintVersion(FILE *s)
{
    fprintf(s, "%s ", AppName);
    PutStringWithNewLine(s, (AppVersion != NULL) ? AppVersion : "(unknown version)");
}

bool HelpOptions::HandleOption(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    switch (id)
    {
    case 'h':
        PrintLongUsage(gActiveOptionSets, stdout);
        exit(EXIT_SUCCESS);
        break;
    case 'v':
        PrintVersion(stdout);
        exit(EXIT_SUCCESS);
        break;
    default:
        PrintArgError("%s: INTERNAL ERROR: Unhandled option: %s\n", progName, name);
        return false;
    }

    return true;
}

// ===== Private/Internal Methods =====

OptionSetBase::OptionSetBase()
{
    OptionHandler = CallHandleFunct;
}

bool OptionSetBase::CallHandleFunct(const char *progName, OptionSet *optSet, int id, const char *name, const char *arg)
{
    return static_cast<OptionSetBase *>(optSet)->HandleOption(progName, optSet, id, name, arg);
}

static char *MakeShortOptions(OptionSet **optSets)
{
    size_t i = 0;

    // Count the number of options.
    size_t totalOptions = CountAllOptions(optSets);

    // Allocate a block of memory big enough to hold the maximum possible size short option string.
    // The buffer needs to be big enough to hold up to 3 characters per short option plus an initial
    // ":" and a terminating null.
    size_t arraySize = 2 + (totalOptions * 3);
    char *shortOpts = (char *)malloc(arraySize);
    if (shortOpts == NULL)
        return NULL;

    // Prefix the string with ':'.  This tells getopt() to signal missing option arguments distinct
    // from unknown options.
    shortOpts[i++] = ':';

    // For each option set...
    for ( ; *optSets != NULL; optSets++)
    {
        // For each option in the current option set...
        for (OptionDef *optDef = (*optSets)->OptionDefs; optDef->Name != NULL; optDef++)
        {
            // If the option id (val) is suitable as a short option character, add it to the short
            // option string. Append ":" if the option requires an argument and "::" if the argument
            // is optional.
            if (IsShortOptionChar(optDef->Id))
            {
                shortOpts[i++] = (char)optDef->Id;
                if (optDef->ArgType != kNoArgument)
                    shortOpts[i++] = ':';
                if (optDef->ArgType == kArgumentOptional)
                    shortOpts[i++] = ':';
            }
        }
    }

    // Terminate the short options string.
    shortOpts[i++] = 0;

    return shortOpts;
}

static struct option *MakeLongOptions(OptionSet **optSets)
{
    size_t totalOptions = CountAllOptions(optSets);

    // Allocate an array to hold the list of long options.
    size_t arraySize = (sizeof(struct option) * (totalOptions + 1));
    struct option *longOpts = (struct option *)malloc(arraySize);
    if (longOpts == NULL)
        return NULL;

    // For each option set...
    size_t i = 0;
    for ( ; *optSets != NULL; optSets++)
    {
        // Copy the option definitions into the long options array.
        for (OptionDef *optDef = (*optSets)->OptionDefs; optDef->Name != NULL; optDef++)
        {
            longOpts[i].name = optDef->Name;
            longOpts[i].has_arg = (int)optDef->ArgType;
            longOpts[i].flag = NULL;
            longOpts[i].val = optDef->Id;
            i++;
        }
    }

    // Terminate the long options array.
    longOpts[i].name = NULL;

    return longOpts;
}

static int32_t SplitArgs(char *argStr, char **& argList, char *initialArg)
{
    enum { InitialArgListSize = 10 };
    int32_t argListSize = 0;
    int32_t argCount = 0;

    // Allocate an array to hold pointers to the arguments.
    argList = (char **)malloc(sizeof(char *) * InitialArgListSize);
    if (argList == NULL)
        return -1;
    argListSize = InitialArgListSize;

    // If an initial argument was supplied, make it the first argument in the array.
    if (initialArg != NULL)
    {
        argList[0] = (char *)initialArg;
        argCount = 1;
    }

    // Parse arguments from the input string until it is exhausted.
    while (true)
    {
        char *nextArg = argStr;

        // Get the argument in the input string.  Note that this modifies the string buffer.
        if (!GetNextArg(argStr))
            break;

        // Grow the arg list array if needed. Note that we reserve one slot at the end of the array
        // for a NULL entry.
        if (argListSize == argCount + 1)
        {
            argListSize *= 2;
            argList = (char **)realloc(argList, argListSize);
            if (argList == NULL)
                return -1;
        }

        // Append the argument.
        argList[argCount++] = nextArg;
    }

    // Set the last element in the array to NULL, but do not include this in the count of elements.
    // This is mandated by the C standard and some versions of getopt_long() depend on it.
    argList[argCount] = NULL;

    return argCount;
}

static bool GetNextArg(char *& parsePoint)
{
    char quoteChar = 0;
    char *argEnd = parsePoint;

    // Skip any leading whitespace.
    while (*parsePoint != 0 && isspace(*parsePoint))
        parsePoint++;

    // Return false if there are no further arguments.
    if (*parsePoint == 0)
        return false;

    // Iterate over characters until we find the end of an argument.
    // As we iterate, we will accumulate the unquoted and unescaped
    // argument characters in the input buffer starting at the initial
    // parsePoint position.
    while (*parsePoint != 0)
    {
        // If the current character is a backslash that is not at the end of
        // the string, skip the backslash but copy the following character
        // verbatim into the argument string.
        if (*parsePoint == '\\' && *(parsePoint + 1) != 0)
        {
            parsePoint++;
        }

        // Otherwise, if not within a quoted substring...
        else if (quoteChar == 0)
        {
            // Whitespace marks the end of the argument.
            if (isspace(*parsePoint))
            {
                parsePoint++;
                break;
            }

            // If the character is a quote character, enter quoted substring mode.
            if (*parsePoint == '"' || *parsePoint == '\'')
            {
                quoteChar = *parsePoint++;
                continue;
            }
        }

        // Otherwise, the parse point is within a quoted substring, so...
        else
        {
            // A corresponding quote character marks the end of the quoted string.
            if (*parsePoint == quoteChar)
            {
                quoteChar = 0;
                parsePoint++;
                continue;
            }
        }

        // Copy the current character to the end of the argument string.
        *argEnd++ = *parsePoint++;
    }

    // Terminate the argument string.
    *argEnd = 0;

    return true;
}

static size_t CountOptionSets(OptionSet **optSets)
{
    size_t count = 0;
    for (; *optSets != NULL; optSets++)
        count++;
    return count;
}

static size_t CountAllOptions(OptionSet **optSets)
{
    size_t count = 0;
    for (; *optSets != NULL; optSets++)
        for (OptionDef *optDef = (*optSets)->OptionDefs; optDef->Name != NULL; optDef++)
            count++;
    return count;
}

static void FindOptionByIndex(OptionSet **optSets, int optIndex, OptionSet *& optSet, OptionDef *& optDef)
{
    for (optSet = *optSets; optSet != NULL; optSet = *++optSets)
        for (optDef = (*optSets)->OptionDefs; optDef->Name != NULL; optDef++)
            if (optIndex-- == 0)
                return;
    optSet = NULL;
    optDef = NULL;
}

static void FindOptionById(OptionSet **optSets, int optId, OptionSet *& optSet, OptionDef *& optDef)
{
    for (optSet = *optSets; optSet != NULL; optSet = *++optSets)
        for (optDef = (*optSets)->OptionDefs; optDef->Name != NULL; optDef++)
            if (optDef->Id == optId)
                return;
    optSet = NULL;
    optDef = NULL;
}

static const char **MakeUniqueHelpGroupNamesList(OptionSet *optSets[])
{
    size_t numOptSets = CountOptionSets(optSets);
    size_t numGroups = 0;

    const char **groupNames = (const char **)malloc(sizeof(const char *) * (numOptSets + 1));
    if (groupNames == NULL)
        return NULL;

    for (size_t optSetIndex = 0; optSetIndex < numOptSets; optSetIndex++)
    {
        if (optSets[optSetIndex] != NULL && optSets[optSetIndex]->OptionDefs[0].Name != NULL)
        {
            for (size_t i = 0; i < numGroups; i++)
                if (strcasecmp(groupNames[i], optSets[optSetIndex]->HelpGroupName) == 0)
                    goto skipDup;
            groupNames[numGroups++] = optSets[optSetIndex]->HelpGroupName;
        skipDup:
            ;
        }
    }

    groupNames[numGroups] = NULL;

    return groupNames;
}

static void PutStringWithNewLine(FILE *s, const char *str)
{
    size_t strLen = strlen(str);
    fputs(str, s);
    if (strLen == 0 || str[strLen-1] != '\n')
        fputs("\n", s);
}

static void PutStringWithBlankLine(FILE *s, const char *str)
{
    size_t strLen = strlen(str);
    fputs(str, s);
    if (strLen < 1 || str[strLen-1] != '\n')
        fputs("\n", s);
    if (strLen < 2 || str[strLen-2] != '\n')
        fputs("\n", s);
}

#if WEAVE_CONFIG_ENABLE_ARG_PARSER_SANTIY_CHECK

static bool SanityCheckOptions(OptionSet *optSets[])
{
    bool res = true;

    // Verify OptionHandler pointer
    for (OptionSet **optSetP = optSets; *optSetP != NULL; optSetP++)
    {
        if ((*optSetP)->OptionHandler == NULL)
        {
            PrintArgError("INTERNAL ERROR: Null OptionHandler in OptionSet (%s)\n", (*optSetP)->HelpGroupName);
            res = false;
        }
    }

    // Verify that no two option sets use the same short option character.
    // (Re-use of the same short option character is allowed within a single option set
    // to allow for aliasing of long options).
    for (OptionSet **optSetP = optSets; *optSetP != NULL; optSetP++)
        for (OptionDef *optionDef = (*optSetP)->OptionDefs; optionDef->Name != NULL; optionDef++)
            if (IsShortOptionChar(optionDef->Id))
            {
                for (OptionSet **optSetP2 = optSets; *optSetP2 != NULL; optSetP2++)
                    if (optSetP2 != optSetP)
                    {
                        for (OptionDef *optionDef2 = (*optSetP2)->OptionDefs; optionDef2->Name != NULL; optionDef2++)
                            if (optionDef->Id == optionDef2->Id)
                            {
                                PrintArgError("INTERNAL ERROR: Multiple command line options configured to use "
                                              "the same short option character (-%c): --%s, --%s\n",
                                              optionDef->Id, optionDef->Name, optionDef2->Name);
                                res = false;
                            }
                    }
            }

    // Fail if the option help texts do not contain a description for each option, including both
    // the option's long and short forms.
    for (OptionSet **optSetP = optSets; *optSetP != NULL; optSetP++)
        for (OptionDef *optionDef = (*optSetP)->OptionDefs; optionDef->Name != NULL; optionDef++)
        {
            if (!HelpTextContainsLongOption(optionDef->Name, (*optSetP)->OptionHelp))
            {
                PrintArgError("INTERNAL ERROR: No help text defined for option: --%s\n", optionDef->Name);
                res = false;
            }

            if (IsShortOptionChar(optionDef->Id) &&
                !HelpTextContainsShortOption(optionDef->Id, (*optSetP)->OptionHelp))
            {
                PrintArgError("INTERNAL ERROR: No help text defined for option: -%c\n", optionDef->Id);
                res = false;
            }
        }

    return res;
}

static bool HelpTextContainsLongOption(const char *optName, const char *helpText)
{
    size_t nameLen = strlen(optName);

    for (const char *p = helpText; (p = strstr(p, optName)) != NULL; p += nameLen)
        if ((p - helpText) >= 2 && p[-1] == '-' && p[-2] == '-' &&
            !isalnum(p[nameLen]) && p[nameLen] != '-')
            return true;

    return false;
}

static bool HelpTextContainsShortOption(char optChar, const char *helpText)
{
    char optStr[3];
    optStr[0] = '-';
    optStr[1] = optChar;
    optStr[2] = 0;

    for (const char *p = helpText; (p = strstr(p, optStr)) != NULL; p += 2)
        if ((p == helpText || (!isalnum(p[-1]) && p[-1] != '-')) &&
            !isalnum(p[2]) && p[2] != '-')
            return true;

    return false;

}

#endif // WEAVE_CONFIG_ENABLE_ARG_PARSER_SANTIY_CHECK

} // namespace ArgParser
} // namespace nl


#endif // WEAVE_CONFIG_ENABLE_ARG_PARSER
