VirtualBox

Ignore:
Timestamp:
May 5, 2015 4:27:52 PM (10 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
100060
Message:

RTGetOptArgvFromString: Added fFlags parameter for selecting the quoting style.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/getoptargv.cpp

    r55529 r55671  
    221221
    222222
    223 RTDECL(int) RTGetOptArgvFromString(char ***ppapszArgv, int *pcArgs, const char *pszCmdLine, const char *pszSeparators)
     223RTDECL(int) RTGetOptArgvFromString(char ***ppapszArgv, int *pcArgs, const char *pszCmdLine,
     224                                   uint32_t fFlags, const char *pszSeparators)
    224225{
    225226    /*
     
    229230    AssertPtr(pcArgs);
    230231    AssertPtr(ppapszArgv);
     232    AssertReturn(   fFlags == RTGETOPTARGV_CNV_QUOTE_BOURNE_SH
     233                 || fFlags == RTGETOPTARGV_CNV_QUOTE_MS_CRT, VERR_INVALID_FLAGS);
    231234    if (!pszSeparators)
    232235        pszSeparators = " \t\n\r";
     
    272275         * Parse and copy the string over.
    273276         */
    274         RTUNICP CpQuote = 0;
    275277        RTUNICP Cp;
    276         for (;;)
    277         {
    278             rc = RTStrGetCpEx(&pszSrc, &Cp);
    279             if (RT_FAILURE(rc) || !Cp)
    280                 break;
    281             if (!CpQuote)
     278        if ((fFlags & RTGETOPTARGV_CNV_QUOTE_MASK) == RTGETOPTARGV_CNV_QUOTE_BOURNE_SH)
     279        {
     280            /*
     281             * Bourne shell style.
     282             */
     283            RTUNICP CpQuote = 0;
     284            for (;;)
    282285            {
    283                 if (Cp == '"' || Cp == '\'')
    284                     CpQuote = Cp;
    285                 else if (rtGetOptIsCpInSet(Cp, pszSeparators, cchSeparators))
     286                rc = RTStrGetCpEx(&pszSrc, &Cp);
     287                if (RT_FAILURE(rc) || !Cp)
     288                    break;
     289                if (!CpQuote)
     290                {
     291                    if (Cp == '"' || Cp == '\'')
     292                        CpQuote = Cp;
     293                    else if (rtGetOptIsCpInSet(Cp, pszSeparators, cchSeparators))
     294                        break;
     295                    else if (Cp != '\\')
     296                        pszDst = RTStrPutCp(pszDst, Cp);
     297                    else
     298                    {
     299                        /* escaped char */
     300                        rc = RTStrGetCpEx(&pszSrc, &Cp);
     301                        if (RT_FAILURE(rc) || !Cp)
     302                            break;
     303                        pszDst = RTStrPutCp(pszDst, Cp);
     304                    }
     305                }
     306                else if (CpQuote != Cp)
     307                {
     308                    if (Cp != '\\' || CpQuote == '\'')
     309                        pszDst = RTStrPutCp(pszDst, Cp);
     310                    else
     311                    {
     312                        /* escaped char */
     313                        rc = RTStrGetCpEx(&pszSrc, &Cp);
     314                        if (RT_FAILURE(rc) || !Cp)
     315                            break;
     316                        pszDst = RTStrPutCp(pszDst, Cp);
     317                    }
     318                }
     319                else
     320                    CpQuote = 0;
     321            }
     322        }
     323        else
     324        {
     325            /*
     326             * Microsoft CRT style.
     327             */
     328            Assert((fFlags & RTGETOPTARGV_CNV_QUOTE_MASK) == RTGETOPTARGV_CNV_QUOTE_MS_CRT);
     329            bool fInQuote;
     330            for (;;)
     331            {
     332                rc = RTStrGetCpEx(&pszSrc, &Cp);
     333                if (RT_FAILURE(rc) || !Cp)
     334                    break;
     335                if (Cp == '"')
     336                    fInQuote = !fInQuote;
     337                else if (!fInQuote && rtGetOptIsCpInSet(Cp, pszSeparators, cchSeparators))
    286338                    break;
    287339                else if (Cp != '\\')
     
    289341                else
    290342                {
    291                     /* escaped char */
    292                     rc = RTStrGetCpEx(&pszSrc, &Cp);
    293                     if (RT_FAILURE(rc) || !Cp)
    294                         break;
    295                     pszDst = RTStrPutCp(pszDst, Cp);
     343                    /* A backslash sequence is only relevant if followed by
     344                       a double quote, then it will work like an escape char. */
     345                    size_t cQuotes = 1;
     346                    while (*pszSrc == '\\')
     347                    {
     348                        cQuotes++;
     349                        pszSrc++;
     350                    }
     351                    if (*pszSrc != '"')
     352                        /* Not an escape sequence.  */
     353                        while (cQuotes-- > 0)
     354                            pszDst = RTStrPutCp(pszDst, '\\');
     355                    else
     356                    {
     357                        /* Escape sequence.  Output half of the slashes.  If odd
     358                           number, output the escaped double quote . */
     359                        while (cQuotes >= 2)
     360                        {
     361                            pszDst = RTStrPutCp(pszDst, '\\');
     362                            cQuotes -= 2;
     363                        }
     364                        if (!cQuotes)
     365                            fInQuote = !fInQuote;
     366                        else
     367                            pszDst = RTStrPutCp(pszDst, '"');
     368                        pszSrc++;
     369                    }
    296370                }
    297371            }
    298             else if (CpQuote != Cp)
    299             {
    300                 if (Cp != '\\' || CpQuote == '\'')
    301                     pszDst = RTStrPutCp(pszDst, Cp);
    302                 else
    303                 {
    304                     /* escaped char */
    305                     rc = RTStrGetCpEx(&pszSrc, &Cp);
    306                     if (RT_FAILURE(rc) || !Cp)
    307                         break;
    308                     pszDst = RTStrPutCp(pszDst, Cp);
    309                 }
    310             }
    311             else
    312                 CpQuote = 0;
    313         }
     372        }
     373
    314374        *pszDst++ = '\0';
    315375        if (RT_FAILURE(rc) || !Cp)
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette