Changeset 2989


Ignore:
Timestamp:
Apr 2, 2007, 4:54:36 AM (18 years ago)
Author:
bird
Message:

New single quote handling.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/libc/src/kNIX/b_initArgv.c

    r2937 r2989  
    9191    for (;;)
    9292    {
     93        /* skip white spaces */
    9394        while (IS_WHITE(*pszSrc))
    9495            ++pszSrc;
    9596        if (*pszSrc == 0)
    9697            break;
    97         char *pfFlags = pbPool;
    98         PUTC((char)_ARG_NONZERO);
     98
     99        /*
     100         * Parse one argument.
     101         */
     102        char fFlags;
     103        char *pfFlags = pbPool ? pbPool++ : &fFlags;
     104        *pfFlags = (char)_ARG_NONZERO;
     105        cbArgs++;
     106        const size_t offArg = cbArgs;
    99107        PUTV;
    100         int cBackspaces = 0;
    101108        char chQuote = 0;
    102109        for (;;)
    103110        {
    104             if (!chQuote ? (*pszSrc == '"' || *pszSrc == '\'') : *pszSrc == chQuote)
     111            /* End quote. */
     112            if (*pszSrc == chQuote && chQuote)
     113                chQuote = 0;
     114            /* Start of double quote. */
     115            else if (!chQuote && *pszSrc == '"')
    105116            {
    106                 while (cBackspaces >= 2)
     117                chQuote = '"';
     118                *pfFlags |= _ARG_DQUOTE;
     119            }
     120            /*
     121             * Only permit the single quote to be used at the start of an argument or
     122             * within an already quoted one. This restriction is necessary to support
     123             * unquoted filenames containing the single quote char.
     124             */
     125            else if (   !chQuote
     126                     && *pszSrc == '\''
     127                     && (   offArg == cbArgs
     128                         || (*pfFlags & _ARG_DQUOTE)))
     129            {
     130                chQuote = '\'';
     131                *pfFlags |= _ARG_DQUOTE;
     132            }
     133            /*
     134             * The escape character. This is truly magic/weird.
     135             * It doesn't escape anything unless it's in front of a
     136             * double quote character. EMX weirdness...
     137             * (Ok, not escaping more than necessary is ok when using \ as path
     138             * separator, but why weird interpretation of \\\\"asdf"?
     139             */
     140            else if (*pszSrc == '\\' && chQuote != '\'')
     141            {
     142                int cSlashes = 0;
     143                do
    107144                {
    108                     PUTC('\\');
    109                     cBackspaces -= 2;
     145                    cSlashes++;
     146                    pszSrc++;
     147                } while (*pszSrc == '\\');
     148
     149                if (*pszSrc == '"')
     150                {
     151                    /* Treat it as escapes. */
     152                    while (cSlashes >= 2)
     153                    {
     154                        PUTC('\\');
     155                        cSlashes -= 2;
     156                    }
     157                    if (cSlashes & 1)
     158                        PUTC(*pszSrc);
     159                    else
     160                        pszSrc--;
    110161                }
    111                 if (cBackspaces & 1)
    112                     PUTC(*pszSrc);
    113162                else
    114163                {
    115                     chQuote = chQuote ? 0 : *pszSrc;
    116                     if (pfFlags != NULL)
    117                         *pfFlags |= _ARG_DQUOTE;
     164                    /* unmodified, no escaping. */
     165                    while (cSlashes-- > 0)
     166                        PUTC('\\');
     167                    pszSrc--;
    118168                }
    119                 cBackspaces = 0;
    120169            }
    121             else if (*pszSrc == '\\')
    122                 ++cBackspaces;
     170            /* Check for end of argument. */
     171            else if (   *pszSrc == '\0'
     172                     || (   IS_WHITE(*pszSrc)
     173                         && !chQuote))
     174                break;
     175            /* Normal character. */
    123176            else
    124             {
    125                 while (cBackspaces != 0)
    126                 {
    127                     PUTC('\\');
    128                     --cBackspaces;
    129                 }
    130                 if (*pszSrc == 0 || (IS_WHITE(*pszSrc) && !chQuote))
    131                     break;
    132177                PUTC(*pszSrc);
    133             }
    134178            ++pszSrc;
    135179        }
Note: See TracChangeset for help on using the changeset viewer.