getopt.cpp revision 3a491eb2162ca9e2024712f737c6317882307e13
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/* $Id$ */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/** @file
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync * IPRT - Command Line Parsing
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/*
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Copyright (C) 2007-2013 Oracle Corporation
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync *
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * available from http://www.virtualbox.org. This file is free software;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * you can redistribute it and/or modify it under the terms of the GNU
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * General Public License (GPL) as published by the Free Software
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync *
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * The contents of this file may alternatively be used under the terms
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * of the Common Development and Distribution License Version 1.0
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * VirtualBox OSE distribution, in which case the provisions of the
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * CDDL are applicable instead of those of the GPL.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync *
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * You may elect to license modified versions of this file under the
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * terms and conditions of either the GPL or the CDDL or both.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/*******************************************************************************
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync* Header Files *
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync*******************************************************************************/
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/cidr.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/net.h> /* must come before getopt.h */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/getopt.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include "internal/iprt.h"
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/assert.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/ctype.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/err.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/message.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/string.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#include <iprt/uuid.h>
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/*******************************************************************************
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync* Global Variables *
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync*******************************************************************************/
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/**
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Standard options that gets included unless RTGETOPTINIT_FLAGS_NO_STD_OPTS is
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * set.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsyncstatic RTGETOPTDEF const g_aStdOptions[] =
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync{
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync { "--help", 'h', RTGETOPT_REQ_NOTHING },
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync { "-help", 'h', RTGETOPT_REQ_NOTHING },
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync { "--version", 'V', RTGETOPT_REQ_NOTHING },
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync { "-version", 'V', RTGETOPT_REQ_NOTHING },
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync};
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync/** The index of --help in g_aStdOptions. Used for some trickery. */
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync#define RTGETOPT_STD_OPTIONS_HELP_IDX 0
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsyncRTDECL(int) RTGetOptInit(PRTGETOPTSTATE pState, int argc, char **argv,
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync PCRTGETOPTDEF paOptions, size_t cOptions,
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync int iFirst, uint32_t fFlags)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync{
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync AssertReturn(!(fFlags & ~(RTGETOPTINIT_FLAGS_OPTS_FIRST | RTGETOPTINIT_FLAGS_NO_STD_OPTS)), VERR_INVALID_PARAMETER);
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync pState->argv = argv;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pState->argc = argc;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync pState->paOptions = paOptions;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pState->cOptions = cOptions;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pState->iNext = iFirst;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pState->pszNextShort = NULL;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->pDef = NULL;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->uIndex = UINT32_MAX;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->fFlags = fFlags;
5b281ba489ca18f0380d7efc7a5108b606cce449vboxsync pState->cNonOptions = 0;
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync /* validate the options. */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync for (size_t i = 0; i < cOptions; i++)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync Assert(!(paOptions[i].fFlags & ~RTGETOPT_VALID_MASK));
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync Assert(paOptions[i].iShort > 0);
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync Assert(paOptions[i].iShort != VINF_GETOPT_NOT_OPTION);
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync Assert(paOptions[i].iShort != '-');
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return VINF_SUCCESS;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync}
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsyncRT_EXPORT_SYMBOL(RTGetOptInit);
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync/**
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * Converts an stringified IPv4 address into the RTNETADDRIPV4 representation.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync *
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @returns VINF_SUCCESS on success, VERR_GETOPT_INVALID_ARGUMENT_FORMAT on
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * failure.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync *
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param pszValue The value to convert.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param pAddr Where to store the result.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsyncstatic int rtgetoptConvertIPv4Addr(const char *pszValue, PRTNETADDRIPV4 pAddr)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync{
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (RT_FAILURE(RTNetStrToIPv4Addr(pszValue, pAddr)))
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return VINF_SUCCESS;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync}
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync/**
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * Converts an stringified Ethernet MAC address into the RTMAC representation.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync *
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @todo This should be move to some generic part of the runtime.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync *
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @returns VINF_SUCCESS on success, VERR_GETOPT_INVALID_ARGUMENT_FORMAT on
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * failure.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync *
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param pszValue The value to convert.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * @param pAddr Where to store the result.
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync */
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsyncstatic int rtgetoptConvertMacAddr(const char *pszValue, PRTMAC pAddr)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync{
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /*
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * Not quite sure if I should accept stuff like "08::27:::1" here...
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * The code is accepting "::" patterns now, except for for the first
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * and last parts.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync */
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync /* first */
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync char *pszNext;
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync int rc = RTStrToUInt8Ex(RTStrStripL(pszValue), &pszNext, 16, &pAddr->au8[0]);
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (*pszNext++ != ':')
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync /* middle */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync for (unsigned i = 1; i < 5; i++)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (*pszNext == ':')
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pAddr->au8[i] = 0;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync else
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &pAddr->au8[i]);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_CHARS)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (*pszNext != ':')
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pszNext++;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync
445661c86e95894713da707c6c9787b7507dfce6vboxsync /* last */
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync rc = RTStrToUInt8Ex(pszNext, &pszNext, 16, &pAddr->au8[5]);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (rc != VINF_SUCCESS && rc != VWRN_TRAILING_SPACES)
445661c86e95894713da707c6c9787b7507dfce6vboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync pszNext = RTStrStripL(pszNext);
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync if (*pszNext)
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VINF_SUCCESS;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync}
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync/**
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * Searches for a long option.
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync *
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * @returns Pointer to a matching option.
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * @param pszOption The alleged long option.
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * @param paOptions Option array.
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync * @param cOptions Number of items in the array.
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * @param fFlags Init flags.
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync */
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsyncstatic PCRTGETOPTDEF rtGetOptSearchLong(const char *pszOption, PCRTGETOPTDEF paOptions, size_t cOptions, uint32_t fFlags)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync{
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync PCRTGETOPTDEF pOpt = paOptions;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync while (cOptions-- > 0)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync if (pOpt->pszLong)
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync {
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync if ((pOpt->fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING)
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync {
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync /*
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync * A value is required with the argument. We're trying to be
c889bbab784ba8552102ce776b6c67b982017861vboxsync * understanding here and will permit any of the following:
c889bbab784ba8552102ce776b6c67b982017861vboxsync * --long12:value, --long12=value, --long12 value,
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync * --long:value, --long=value, --long value,
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync *
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * If the option is index, then all trailing chars must be
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync * digits. For error reporting reasons we also match where
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * there is no index.
c5d2523548cc57504b829f53f1362b848a84542cvboxsync */
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync size_t cchLong = strlen(pOpt->pszLong);
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if ( !strncmp(pszOption, pOpt->pszLong, cchLong)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync && !RTStrNICmp(pszOption, pOpt->pszLong, cchLong)))
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync while (RT_C_IS_DIGIT(pszOption[cchLong]))
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync cchLong++;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if ( pszOption[cchLong] == '\0'
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync || pszOption[cchLong] == ':'
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync || pszOption[cchLong] == '=')
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return pOpt;
771c393ea3dea8143cabc5c8ff6b5cd38a1db91evboxsync }
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync }
234af146205f61c4aa0be736abb06601a89facb8vboxsync else if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
234af146205f61c4aa0be736abb06601a89facb8vboxsync {
234af146205f61c4aa0be736abb06601a89facb8vboxsync /*
234af146205f61c4aa0be736abb06601a89facb8vboxsync * The option takes an index but no value.
234af146205f61c4aa0be736abb06601a89facb8vboxsync * As above, we also match where there is no index.
234af146205f61c4aa0be736abb06601a89facb8vboxsync */
234af146205f61c4aa0be736abb06601a89facb8vboxsync size_t cchLong = strlen(pOpt->pszLong);
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if ( !strncmp(pszOption, pOpt->pszLong, cchLong)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync && !RTStrNICmp(pszOption, pOpt->pszLong, cchLong)))
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync while (RT_C_IS_DIGIT(pszOption[cchLong]))
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync cchLong++;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (pszOption[cchLong] == '\0')
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync return pOpt;
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync }
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync else if ( !strcmp(pszOption, pOpt->pszLong)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync && !RTStrICmp(pszOption, pOpt->pszLong)))
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return pOpt;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync pOpt++;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (!(fFlags & RTGETOPTINIT_FLAGS_NO_STD_OPTS))
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync for (uint32_t i = 0; i < RT_ELEMENTS(g_aStdOptions); i++)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if ( !strcmp(pszOption, g_aStdOptions[i].pszLong)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync || ( pOpt->fFlags & RTGETOPT_FLAG_ICASE
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync && !RTStrICmp(pszOption, g_aStdOptions[i].pszLong)))
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return &g_aStdOptions[i];
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return NULL;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync}
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync/**
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * Searches for a matching short option.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync *
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @returns Pointer to a matching option.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param chOption The option char.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param paOptions Option array.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * @param cOptions Number of items in the array.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param fFlags Init flags.
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsyncstatic PCRTGETOPTDEF rtGetOptSearchShort(int chOption, PCRTGETOPTDEF paOptions, size_t cOptions, uint32_t fFlags)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync{
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync PCRTGETOPTDEF pOpt = paOptions;
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync while (cOptions-- > 0)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (pOpt->iShort == chOption)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return pOpt;
1829a716128b3e2d42bcee064a15c553dbd44798vboxsync pOpt++;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (!(fFlags & RTGETOPTINIT_FLAGS_NO_STD_OPTS))
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync for (uint32_t i = 0; i < RT_ELEMENTS(g_aStdOptions); i++)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (g_aStdOptions[i].iShort == chOption)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return &g_aStdOptions[i];
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync if (chOption == '?')
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return &g_aStdOptions[RTGETOPT_STD_OPTIONS_HELP_IDX];
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync return NULL;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync}
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync/**
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * Value string -> Value union.
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync *
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync * @returns IPRT status code.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param fFlags The value flags.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param pszValue The value string.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param pValueUnion Where to return the processed value.
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsyncstatic int rtGetOptProcessValue(uint32_t fFlags, const char *pszValue, PRTGETOPTUNION pValueUnion)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync{
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync /*
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync * Transform into a option value as requested.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * If decimal conversion fails, we'll check for "0x<xdigit>" and
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * try a 16 based conversion. We will not interpret any of the
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * generic ints as octals.
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync switch (fFlags & ( RTGETOPT_REQ_MASK
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync | RTGETOPT_FLAG_HEX
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync | RTGETOPT_FLAG_DEC
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync | RTGETOPT_FLAG_OCT))
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync case RTGETOPT_REQ_STRING:
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync pValueUnion->psz = pszValue;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync break;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync case RTGETOPT_REQ_BOOL:
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if ( !RTStrICmp(pszValue, "true")
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync || !RTStrICmp(pszValue, "t")
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync || !RTStrICmp(pszValue, "yes")
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync || !RTStrICmp(pszValue, "y")
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync || !RTStrICmp(pszValue, "enabled")
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync || !RTStrICmp(pszValue, "enable")
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync || !RTStrICmp(pszValue, "en")
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync || !RTStrICmp(pszValue, "e")
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync || !RTStrICmp(pszValue, "on")
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync || !RTStrCmp(pszValue, "1")
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync )
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync pValueUnion->f = true;
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync else if ( !RTStrICmp(pszValue, "false")
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync || !RTStrICmp(pszValue, "f")
771c393ea3dea8143cabc5c8ff6b5cd38a1db91evboxsync || !RTStrICmp(pszValue, "no")
234af146205f61c4aa0be736abb06601a89facb8vboxsync || !RTStrICmp(pszValue, "n")
234af146205f61c4aa0be736abb06601a89facb8vboxsync || !RTStrICmp(pszValue, "disabled")
234af146205f61c4aa0be736abb06601a89facb8vboxsync || !RTStrICmp(pszValue, "disable")
234af146205f61c4aa0be736abb06601a89facb8vboxsync || !RTStrICmp(pszValue, "dis")
234af146205f61c4aa0be736abb06601a89facb8vboxsync || !RTStrICmp(pszValue, "d")
234af146205f61c4aa0be736abb06601a89facb8vboxsync || !RTStrICmp(pszValue, "off")
234af146205f61c4aa0be736abb06601a89facb8vboxsync || !RTStrCmp(pszValue, "0")
234af146205f61c4aa0be736abb06601a89facb8vboxsync )
234af146205f61c4aa0be736abb06601a89facb8vboxsync pValueUnion->f = false;
234af146205f61c4aa0be736abb06601a89facb8vboxsync else
234af146205f61c4aa0be736abb06601a89facb8vboxsync {
234af146205f61c4aa0be736abb06601a89facb8vboxsync pValueUnion->psz = pszValue;
234af146205f61c4aa0be736abb06601a89facb8vboxsync return VERR_GETOPT_UNKNOWN_OPTION;
234af146205f61c4aa0be736abb06601a89facb8vboxsync }
234af146205f61c4aa0be736abb06601a89facb8vboxsync break;
234af146205f61c4aa0be736abb06601a89facb8vboxsync
234af146205f61c4aa0be736abb06601a89facb8vboxsync case RTGETOPT_REQ_BOOL_ONOFF:
234af146205f61c4aa0be736abb06601a89facb8vboxsync if (!RTStrICmp(pszValue, "on"))
234af146205f61c4aa0be736abb06601a89facb8vboxsync pValueUnion->f = true;
234af146205f61c4aa0be736abb06601a89facb8vboxsync else if (!RTStrICmp(pszValue, "off"))
ad836b4d6fb2ccaf969666246c2c389a8d10ca41vboxsync pValueUnion->f = false;
ad836b4d6fb2ccaf969666246c2c389a8d10ca41vboxsync else
234af146205f61c4aa0be736abb06601a89facb8vboxsync {
234af146205f61c4aa0be736abb06601a89facb8vboxsync pValueUnion->psz = pszValue;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_UNKNOWN_OPTION;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync }
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync break;
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync#define MY_INT_CASE(req, type, memb, convfn) \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync case req: \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync { \
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync type Value; \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if ( convfn(pszValue, 10, &Value) != VINF_SUCCESS \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync && ( pszValue[0] != '0' \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync || (pszValue[1] != 'x' && pszValue[1] != 'X') \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync || !RT_C_IS_XDIGIT(pszValue[2]) \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync || convfn(pszValue, 16, &Value) != VINF_SUCCESS ) ) \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pValueUnion->memb = Value; \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync break; \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync#define MY_BASE_INT_CASE(req, type, memb, convfn, base) \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync case req: \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync { \
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync type Value; \
234af146205f61c4aa0be736abb06601a89facb8vboxsync if (convfn(pszValue, base, &Value) != VINF_SUCCESS) \
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT; \
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pValueUnion->memb = Value; \
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync break; \
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_INT_CASE(RTGETOPT_REQ_INT8, int8_t, i8, RTStrToInt8Full)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_INT_CASE(RTGETOPT_REQ_INT16, int16_t, i16, RTStrToInt16Full)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_INT_CASE(RTGETOPT_REQ_INT32, int32_t, i32, RTStrToInt32Full)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_INT_CASE(RTGETOPT_REQ_INT64, int64_t, i64, RTStrToInt64Full)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_INT_CASE(RTGETOPT_REQ_UINT8, uint8_t, u8, RTStrToUInt8Full)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_INT_CASE(RTGETOPT_REQ_UINT16, uint16_t, u16, RTStrToUInt16Full)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_INT_CASE(RTGETOPT_REQ_UINT32, uint32_t, u32, RTStrToUInt32Full)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_INT_CASE(RTGETOPT_REQ_UINT64, uint64_t, u64, RTStrToUInt64Full)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT8 | RTGETOPT_FLAG_HEX, int8_t, i8, RTStrToInt8Full, 16)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT16 | RTGETOPT_FLAG_HEX, int16_t, i16, RTStrToInt16Full, 16)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_HEX, int32_t, i32, RTStrToInt32Full, 16)
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT64 | RTGETOPT_FLAG_HEX, int64_t, i64, RTStrToInt64Full, 16)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8 | RTGETOPT_FLAG_HEX, uint8_t, u8, RTStrToUInt8Full, 16)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_HEX, uint16_t, u16, RTStrToUInt16Full, 16)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_HEX, uint32_t, u32, RTStrToUInt32Full, 16)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_HEX, uint64_t, u64, RTStrToUInt64Full, 16)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT8 | RTGETOPT_FLAG_DEC, int8_t, i8, RTStrToInt8Full, 10)
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT16 | RTGETOPT_FLAG_DEC, int16_t, i16, RTStrToInt16Full, 10)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_DEC, int32_t, i32, RTStrToInt32Full, 10)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT64 | RTGETOPT_FLAG_DEC, int64_t, i64, RTStrToInt64Full, 10)
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8 | RTGETOPT_FLAG_DEC, uint8_t, u8, RTStrToUInt8Full, 10)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_DEC, uint16_t, u16, RTStrToUInt16Full, 10)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_DEC, uint32_t, u32, RTStrToUInt32Full, 10)
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_DEC, uint64_t, u64, RTStrToUInt64Full, 10)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT8 | RTGETOPT_FLAG_OCT, int8_t, i8, RTStrToInt8Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT16 | RTGETOPT_FLAG_OCT, int16_t, i16, RTStrToInt16Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT32 | RTGETOPT_FLAG_OCT, int32_t, i32, RTStrToInt32Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_INT64 | RTGETOPT_FLAG_OCT, int64_t, i64, RTStrToInt64Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT8 | RTGETOPT_FLAG_OCT, uint8_t, u8, RTStrToUInt8Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT16 | RTGETOPT_FLAG_OCT, uint16_t, u16, RTStrToUInt16Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT32 | RTGETOPT_FLAG_OCT, uint32_t, u32, RTStrToUInt32Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync MY_BASE_INT_CASE(RTGETOPT_REQ_UINT64 | RTGETOPT_FLAG_OCT, uint64_t, u64, RTStrToUInt64Full, 8)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync#undef MY_INT_CASE
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync#undef MY_BASE_INT_CASE
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync case RTGETOPT_REQ_IPV4ADDR:
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync RTNETADDRIPV4 Addr;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync if (rtgetoptConvertIPv4Addr(pszValue, &Addr) != VINF_SUCCESS)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->IPv4Addr = Addr;
041d531fb5794a8a4cf6c35886d89ec25cbbdde2vboxsync break;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync }
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync case RTGETOPT_REQ_IPV4CIDR:
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync RTNETADDRIPV4 network;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync RTNETADDRIPV4 netmask;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync if (RT_FAILURE(RTCidrStrToIPv4(pszValue, &network, &netmask)))
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->CidrIPv4.IPv4Network.u = network.u;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->CidrIPv4.IPv4Netmask.u = netmask.u;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync break;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync }
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync case RTGETOPT_REQ_MACADDR:
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync {
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync RTMAC Addr;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync if (rtgetoptConvertMacAddr(pszValue, &Addr) != VINF_SUCCESS)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->MacAddr = Addr;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync break;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync case RTGETOPT_REQ_UUID:
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync {
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync RTUUID Uuid;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync if (RTUuidFromStr(&Uuid, pszValue) != VINF_SUCCESS)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->Uuid = Uuid;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync break;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync }
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync default:
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync AssertMsgFailed(("f=%#x\n", fFlags));
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return VERR_INTERNAL_ERROR;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync }
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return VINF_SUCCESS;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync}
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync/**
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * Moves one argv option entries.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync *
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * @param papszTo Destination.
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync * @param papszFrom Source.
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync */
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsyncstatic void rtGetOptMoveArgvEntries(char **papszTo, char **papszFrom)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync{
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync if (papszTo != papszFrom)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync {
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync Assert((uintptr_t)papszTo < (uintptr_t)papszFrom);
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync char * const pszMoved = papszFrom[0];
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync memmove(&papszTo[1], &papszTo[0], (uintptr_t)papszFrom - (uintptr_t)papszTo);
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync papszTo[0] = pszMoved;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync }
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync}
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsyncRTDECL(int) RTGetOpt(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync{
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync /*
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync * Reset the variables kept in state.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->pDef = NULL;
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync pState->uIndex = UINT32_MAX;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync /*
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync * Make sure the union is completely cleared out, whatever happens below.
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync */
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync pValueUnion->u64 = 0;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->pDef = NULL;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync /*
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync * The next option.
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync */
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync bool fShort;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync int iThis;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync const char *pszArgThis;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync PCRTGETOPTDEF pOpt;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync if (pState->pszNextShort)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync {
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync /*
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync * We've got short options left over from the previous call.
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync */
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync pOpt = rtGetOptSearchShort(*pState->pszNextShort, pState->paOptions, pState->cOptions, pState->fFlags);
ad27e1d5e48ca41245120c331cc88b50464813cevboxsync if (!pOpt)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync {
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync pValueUnion->psz = pState->pszNextShort;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync return VERR_GETOPT_UNKNOWN_OPTION;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync }
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync pState->pszNextShort++;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync pszArgThis = pState->pszNextShort - 2;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync iThis = pState->iNext;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync fShort = true;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync }
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync else
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /*
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Pop off the next argument. Sorting options and dealing with the
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync * dash-dash makes this a little extra complicated.
c5d2523548cc57504b829f53f1362b848a84542cvboxsync */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync for (;;)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync {
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync if (pState->iNext >= pState->argc)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync return 0;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
c5d2523548cc57504b829f53f1362b848a84542cvboxsync if (pState->cNonOptions)
c5d2523548cc57504b829f53f1362b848a84542cvboxsync {
c5d2523548cc57504b829f53f1362b848a84542cvboxsync if (pState->cNonOptions == INT32_MAX)
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pValueUnion->psz = pState->argv[pState->iNext++];
a9ed90fc7da3c371bc3b96c8535655b87836fcadvboxsync return VINF_GETOPT_NOT_OPTION;
8929a16e87a515b7071399479548158b8c5fbdd2vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync if (pState->iNext + pState->cNonOptions >= pState->argc)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->cNonOptions = INT32_MAX;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync continue;
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
e4527e0a08e2d635a679ae2947d42195f30a2ce2vboxsync iThis = pState->iNext++;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pszArgThis = pState->argv[iThis + pState->cNonOptions];
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /*
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Do a long option search first and then a short option one.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * This way we can make sure single dash long options doesn't
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync * get mixed up with short ones.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync pOpt = rtGetOptSearchLong(pszArgThis, pState->paOptions, pState->cOptions, pState->fFlags);
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if ( !pOpt
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync && pszArgThis[0] == '-'
7f18b4c79440e724c5e08f007674ea7883ce6c01vboxsync && pszArgThis[1] != '-'
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync && pszArgThis[1] != '\0')
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
db3d025f28c59aececbbda4174fa513496c89b2bvboxsync pOpt = rtGetOptSearchShort(pszArgThis[1], pState->paOptions, pState->cOptions, pState->fFlags);
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync fShort = pOpt != NULL;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync else
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync fShort = false;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync /* Look for dash-dash. */
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (!pOpt && !strcmp(pszArgThis, "--"))
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pState->cNonOptions = INT32_MAX;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync continue;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f18b4c79440e724c5e08f007674ea7883ce6c01vboxsync /* Options first hacks. */
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (pState->fFlags & RTGETOPTINIT_FLAGS_OPTS_FIRST)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (pOpt)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]);
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync else if (*pszArgThis == '-')
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pValueUnion->psz = pszArgThis;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_UNKNOWN_OPTION;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync else
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync /* not an option, add it to the non-options and try again. */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->iNext--;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync pState->cNonOptions++;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync /* Switch to returning non-options if we've reached the end. */
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (pState->iNext + pState->cNonOptions >= pState->argc)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync pState->cNonOptions = INT32_MAX;
7f18b4c79440e724c5e08f007674ea7883ce6c01vboxsync continue;
7f18b4c79440e724c5e08f007674ea7883ce6c01vboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /* done */
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync break;
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync }
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync if (pOpt)
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync {
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync pValueUnion->pDef = pOpt; /* in case of no value or error. */
7f18b4c79440e724c5e08f007674ea7883ce6c01vboxsync
7f18b4c79440e724c5e08f007674ea7883ce6c01vboxsync if ((pOpt->fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /*
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Find the argument value.
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync *
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * A value is required with the argument. We're trying to be
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync * understanding here and will permit any of the following:
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * -svalue, -s value, -s:value and -s=value
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * (Ditto for long options.)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync */
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync const char *pszValue;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (fShort)
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync {
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync if (pszArgThis[2] == '\0')
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (iThis + 1 >= pState->argc)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pszValue = pState->argv[iThis + pState->cNonOptions + 1];
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pState->iNext++;
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync }
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync else /* same argument. */
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync pszValue = &pszArgThis[2 + (pszArgThis[2] == ':' || pszArgThis[2] == '=')];
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync if (pState->pszNextShort)
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync {
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync pState->pszNextShort = NULL;
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync pState->iNext++;
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync }
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync else
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync size_t cchLong = strlen(pOpt->pszLong);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (pszArgThis[cchLong] == '\0')
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_INDEX_MISSING;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync uint32_t uIndex;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync char *pszRet = NULL;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync int rc = RTStrToUInt32Ex(&pszArgThis[cchLong], &pszRet, 10, &uIndex);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (rc == VWRN_TRAILING_CHARS)
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync {
0ff2f0d33dea0e82857c2131d43f637c206a8163vboxsync if ( pszRet[0] != ':'
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync && pszRet[0] != '=')
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_INVALID_ARGUMENT_FORMAT;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pState->uIndex = uIndex;
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync pszValue = pszRet + 1;
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync }
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync else if (rc == VINF_SUCCESS)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (iThis + 1 >= pState->argc)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pState->uIndex = uIndex;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pszValue = pState->argv[iThis + pState->cNonOptions + 1];
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]);
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync pState->iNext++;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync else
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync else
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (pszArgThis[cchLong] == '\0')
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (iThis + 1 >= pState->argc)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pszValue = pState->argv[iThis + pState->cNonOptions + 1];
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync rtGetOptMoveArgvEntries(&pState->argv[iThis + 1], &pState->argv[iThis + pState->cNonOptions + 1]);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync pState->iNext++;
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync else /* same argument. */
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pszValue = &pszArgThis[cchLong + 1];
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync }
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync /*
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync * Set up the ValueUnion.
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync */
e5bfc5c34142a7550be3564a8e01a037b1db5b31vboxsync int rc = rtGetOptProcessValue(pOpt->fFlags, pszValue, pValueUnion);
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync if (RT_FAILURE(rc))
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync return rc;
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync }
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync else if (fShort)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync /*
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * Deal with "compressed" short option lists, correcting the next
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync * state variables for the start and end cases.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync */
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync if (pszArgThis[2])
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync {
c5d2523548cc57504b829f53f1362b848a84542cvboxsync if (!pState->pszNextShort)
d60d5da33bb93fc7a8717802f21b13aa37914799vboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /* start */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->pszNextShort = &pszArgThis[2];
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->iNext--;
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync }
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync else if (pState->pszNextShort)
fbb3513a43135c633f7f51544c4bdfce748929bfvboxsync {
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync /* end */
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->pszNextShort = NULL;
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync pState->iNext++;
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync }
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync }
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync else if (pOpt->fFlags & RTGETOPT_FLAG_INDEX)
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync {
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync size_t cchLong = strlen(pOpt->pszLong);
ee6e48c229ef52aee5e968d956ebd066073811abvboxsync if (pszArgThis[cchLong] == '\0')
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync return VERR_GETOPT_INDEX_MISSING;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
a9ed90fc7da3c371bc3b96c8535655b87836fcadvboxsync uint32_t uIndex;
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync if (RTStrToUInt32Full(&pszArgThis[cchLong], 10, &uIndex) == VINF_SUCCESS)
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync pState->uIndex = uIndex;
c889bbab784ba8552102ce776b6c67b982017861vboxsync else
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync AssertMsgFailedReturn(("%s\n", pszArgThis), VERR_GETOPT_INVALID_ARGUMENT_FORMAT); /* search bug */
5eda82e218d35ae0691febd531e1bfc0324cc4a6vboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync pState->pDef = pOpt;
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync return pOpt->iShort;
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync }
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
c5d2523548cc57504b829f53f1362b848a84542cvboxsync /*
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync * Not a known option argument. If it starts with a switch char (-) we'll
ad1e35f9fb71d147c2126449a25adf0f8e155aaavboxsync * fail with unknown option, and if it doesn't we'll return it as a non-option.
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync */
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync if (*pszArgThis == '-')
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync {
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->psz = pszArgThis;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return VERR_GETOPT_UNKNOWN_OPTION;
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync }
c889bbab784ba8552102ce776b6c67b982017861vboxsync
c889bbab784ba8552102ce776b6c67b982017861vboxsync pValueUnion->psz = pszArgThis;
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync return VINF_GETOPT_NOT_OPTION;
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync}
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsyncRT_EXPORT_SYMBOL(RTGetOpt);
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsyncRTDECL(int) RTGetOptFetchValue(PRTGETOPTSTATE pState, PRTGETOPTUNION pValueUnion, uint32_t fFlags)
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync{
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync /*
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync * Validate input.
c889bbab784ba8552102ce776b6c67b982017861vboxsync */
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync PCRTGETOPTDEF pOpt = pState->pDef;
c889bbab784ba8552102ce776b6c67b982017861vboxsync AssertReturn(!(fFlags & ~RTGETOPT_VALID_MASK), VERR_INVALID_PARAMETER);
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync AssertReturn((fFlags & RTGETOPT_REQ_MASK) != RTGETOPT_REQ_NOTHING, VERR_INVALID_PARAMETER);
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync /*
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync * Make sure the union is completely cleared out, whatever happens below.
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync */
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->u64 = 0;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync pValueUnion->pDef = NULL;
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync /*
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync * Pop off the next argument and convert it into a value union.
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync */
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync if (pState->iNext >= pState->argc)
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync return VERR_GETOPT_REQUIRED_ARGUMENT_MISSING;
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync int iThis = pState->iNext++;
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync const char *pszValue = pState->argv[iThis + (pState->cNonOptions != INT32_MAX ? pState->cNonOptions : 0)];
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync pValueUnion->pDef = pOpt; /* in case of no value or error. */
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync if (pState->cNonOptions && pState->cNonOptions != INT32_MAX)
81fcf0038d2d6c76ab2c8b02103dc18c24efe0a1vboxsync rtGetOptMoveArgvEntries(&pState->argv[iThis], &pState->argv[iThis + pState->cNonOptions]);
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync return rtGetOptProcessValue(fFlags, pszValue, pValueUnion);
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync}
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsyncRT_EXPORT_SYMBOL(RTGetOptFetchValue);
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsyncRTDECL(RTEXITCODE) RTGetOptPrintError(int ch, PCRTGETOPTUNION pValueUnion)
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync{
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync if (ch == VINF_GETOPT_NOT_OPTION)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync RTMsgError("Invalid parameter: %s", pValueUnion->psz);
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync else if (ch > 0)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync {
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync if (RT_C_IS_GRAPH(ch))
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync RTMsgError("Unhandled option: -%c", ch);
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync else
4d32c71a938b979c6aeee321ae325d5793a5ccdbvboxsync RTMsgError("Unhandled option: %i (%#x)", ch, ch);
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync }
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync else if (ch == VERR_GETOPT_UNKNOWN_OPTION)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync RTMsgError("Unknown option: '%s'", pValueUnion->psz);
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync else if (ch == VERR_GETOPT_INVALID_ARGUMENT_FORMAT)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync /** @todo r=klaus not really ideal, as the value isn't available */
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync RTMsgError("The value given '%s' has an invalid format.", pValueUnion->pDef->pszLong);
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync else if (pValueUnion->pDef)
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync RTMsgError("%s: %Rrs\n", pValueUnion->pDef->pszLong, ch);
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync else
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync RTMsgError("%Rrs\n", ch);
7f4b4ec1cadbf891d2756ce77dc4a4ec220a03bcvboxsync
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync return RTEXITCODE_SYNTAX;
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsync}
00cc5d93f7446d9394a0f6b7ad790b9fb9d6005cvboxsyncRT_EXPORT_SYMBOL(RTGetOptPrintError);
ab02aeaf2a0312fe9267a292e3911728e4531332vboxsync
833f83ce101b6e9168f519decc0dc7a1079d35f7vboxsync