Changeset 2990 for branches


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

New single quote handling, Fixes #136.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • branches/libc-0.6/src/emx/src/lib/sys/__init.c

    r2021 r2990  
    4545*******************************************************************************/
    4646static int parse_args(const char *src, char **argv, char *pool);
     47static int verify_end_of_single_quote(const char *src);
    4748
    4849
     
    7980static int parse_args(const char *src, char **argv, char *pool)
    8081{
    81     int bs, quote;
     82    int   quote;
     83    char  flags;
    8284    char *flag_ptr;
    83     int   arg_size;
     85    int   arg_size, arg_pos;
    8486
    8587    argc = 0; arg_size = 0;
     
    101103        if (*src == 0)
    102104            break;
    103         flag_ptr = pool;
    104         PUTC((char)_ARG_NONZERO);
     105        if (!pool)
     106        {
     107            flags = _ARG_NONZERO;
     108            flag_ptr = &flags;
     109            arg_size++;
     110        }
     111        else
     112        {
     113            flag_ptr = pool;
     114            PUTC((char)_ARG_NONZERO);
     115        }
     116        arg_pos = arg_size;
    105117        PUTV;
    106         bs = 0; quote = 0;
     118        quote = 0;
    107119        for (;;)
    108120        {
    109             if (!quote ? (*src == '"' || *src == '\'') : *src == quote)
     121            /* End quote. */
     122            if (*src == quote && quote)
     123                quote = 0;
     124            /* Start of double quote. */
     125            else if (!quote && *src == '"')
    110126            {
    111                 while (bs >= 2)
     127                quote = '"';
     128                *flag_ptr |= _ARG_DQUOTE;
     129            }
     130            /*
     131             * Only permit the single quote to be used at the start of an argument or
     132             * within an already quoted one. This restriction is necessary to support
     133             * unquoted filenames containing the single quote char.
     134             */
     135            else if (   !quote && *src == '\''
     136                     && (   arg_pos == arg_size
     137                         || (*flag_ptr & _ARG_DQUOTE)))
     138            {
     139                quote = '\'';
     140                *flag_ptr |= _ARG_DQUOTE;
     141            }
     142            /*
     143             * The escape character. This is truly magic/weird.
     144             * It doesn't escape anything unless it's in front of a
     145             * double quote character. EMX weirdness...
     146             * (Ok, not escaping more than necessary is ok when using \ as path
     147             * separator, but why weird interpretation of \\\\"asdf"?
     148             */
     149            else if (*src == '\\' && quote != '\'')
     150            {
     151                int cSlashes = 0;
     152                do
    112153                {
    113                     PUTC('\\');
    114                     bs -= 2;
     154                    cSlashes++;
     155                    src++;
     156                } while (*src == '\\');
     157
     158                if (*src == '"')
     159                {
     160                    /* Treat it is as escapes. */
     161                    while (cSlashes >= 2)
     162                    {
     163                        PUTC('\\');
     164                        cSlashes -= 2;
     165                    }
     166                    if (cSlashes & 1)
     167                        PUTC(*src);
     168                    else
     169                        src--;
    115170                }
    116                 if (bs & 1)
    117                     PUTC(*src);
    118171                else
    119172                {
    120                     quote = quote ? 0 : *src;
    121                     if (flag_ptr != NULL)
    122                         *flag_ptr |= _ARG_DQUOTE;
     173                    /* unmodified, no escaping. */
     174                    while (cSlashes-- > 0)
     175                        PUTC('\\');
     176                    src--;
    123177                }
    124                 bs = 0;
    125178            }
    126             else if (*src == '\\')
    127                 ++bs;
     179            /* Check for end of argument. */
     180            else if (*src == 0 || (WHITE(*src) && !quote))
     181                break;
     182            /* Normal character. */
    128183            else
    129             {
    130                 while (bs != 0)
    131                 {
    132                     PUTC('\\');
    133                     --bs;
    134                 }
    135                 if (*src == 0 || (WHITE(*src) && !quote))
    136                     break;
    137184                PUTC(*src);
    138             }
    139185            ++src;
    140186        }
     
    143189    return arg_size;
    144190}
     191
     192
     193/**
     194 * This is a hack to prevent us from messing up filenames that
     195 * include a \' character.
     196 * 
     197 * @param src
     198 *
     199 * @return int
     200 */
     201static int verify_end_of_single_quote(const char *src);
    145202
    146203
Note: See TracChangeset for help on using the changeset viewer.