getoptargv.cpp revision b6cc4092c1e80655a5bc19dc125e772a8d2b870d
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * IPRT - Command Line Parsing, Argument Vector.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Copyright (C) 2010 Sun Microsystems, Inc.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * This file is part of VirtualBox Open Source Edition (OSE), as
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * available from http://www.virtualbox.org. This file is free software;
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * you can redistribute it and/or modify it under the terms of the GNU
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * General Public License (GPL) as published by the Free Software
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Foundation, in version 2 as it comes in the "COPYING" file of the
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * VirtualBox OSE distribution. VirtualBox OSE is distributed in the
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * The contents of this file may alternatively be used under the terms
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * of the Common Development and Distribution License Version 1.0
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * (CDDL) only, as it comes in the "COPYING.CDDL" file of the
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * VirtualBox OSE distribution, in which case the provisions of the
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * CDDL are applicable instead of those of the GPL.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * You may elect to license modified versions of this file under the
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * terms and conditions of either the GPL or the CDDL or both.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Clara, CA 95054 USA or visit http://www.sun.com if you need
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * additional information or have any questions.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync/*******************************************************************************
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync* Header Files *
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync*******************************************************************************/
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Look for an unicode code point in the separator string.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @returns true if it's a separator, false if it isn't.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param Cp The code point.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param pszSeparators The separators.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsyncstatic bool rtGetOptIsUniCpInString(RTUNICP Cp, const char *pszSeparators)
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync /* This could be done in a more optimal fashion. Probably worth a
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync separate RTStr function at some point. */
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync return true;
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync return false;
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Look for an 7-bit ASCII character in the separator string.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @returns true if it's a separator, false if it isn't.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param ch The character.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param pszSeparators The separators.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param cchSeparators The number of separators chars.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsyncDECLINLINE(bool) rtGetOptIsAsciiInSet(char ch, const char *pszSeparators, size_t cchSeparators)
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync return false;
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Checks if the character is in the set of separators
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @returns true if it is, false if it isn't.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param Cp The code point.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param pszSeparators The separators.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param cchSeparators The length of @a pszSeparators.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsyncDECL_FORCE_INLINE(bool) rtGetOptIsCpInSet(RTUNICP Cp, const char *pszSeparators, size_t cchSeparators)
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync return rtGetOptIsAsciiInSet((char)Cp, pszSeparators, cchSeparators);
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Skips any delimiters at the start of the string that is pointed to.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @returns VINF_SUCCESS or RTStrGetCpEx status code.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param ppszSrc Where to get and return the string pointer.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param pszSeparators The separators.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * @param cchSeparators The length of @a pszSeparators.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsyncstatic int rtGetOptSkipDelimiters(const char **ppszSrc, const char *pszSeparators, size_t cchSeparators)
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync const char *pszRet;
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync || !rtGetOptIsCpInSet(Cp, pszSeparators, cchSeparators))
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsyncRTDECL(int) RTGetOptArgvFromString(char ***ppapszArgv, int *pcArgs, const char *pszCmdLine, const char *pszSeparators)
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Some input validation.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync size_t const cchSeparators = strlen(pszSeparators);
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync AssertReturn(cchSeparators > 0, VERR_INVALID_PARAMETER);
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Parse the command line and chop off it into argv individual argv strings.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync char *pszDup = (char *)RTMemAlloc(strlen(pszSrc) + 1);
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync unsigned iArg = 0;
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync /* Skip stuff */
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync rc = rtGetOptSkipDelimiters(&pszSrc, pszSeparators, cchSeparators);
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync /* Start a new entry. */
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync void *pvNew = RTMemRealloc(papszArgs, (iArg + 33) * sizeof(char *));
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync /* Parse and copy the string over. */
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync else if (rtGetOptIsCpInSet(Cp, pszSeparators, cchSeparators))
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Terminate the array.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * Check for empty string to make sure we've got an array.
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync papszArgs = (char **)RTMemAlloc(1 * sizeof(char *));
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync/** @todo RTGetOptArgvToString (for windows)?
b6cc4092c1e80655a5bc19dc125e772a8d2b870dvboxsync * RTGetOptArgvSort for RTGetOptInit()? */