VirtualBox

Changeset 2839 in kBuild for trunk/src/kmk/kmkbuiltin/redirect.c


Ignore:
Timestamp:
Aug 25, 2016 9:46:44 PM (9 years ago)
Author:
bird
Message:

kWorker: A little more hacking.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/kmkbuiltin/redirect.c

    r2822 r2839  
    4141# include <direct.h>
    4242# include <process.h>
     43# include "quote_argv.h"
    4344#else
    4445# include <unistd.h>
     
    6263
    6364#if defined(_MSC_VER)
    64 
    65 /**
    66  * Checks if this is an Watcom option where we must just pass thru the string
    67  * as-is.
    68  *
    69  * This is currnetly only used for -d (defining macros).
    70  *
    71  * @returns 1 if pass-thru, 0 if not.
    72  * @param   pszArg          The argument to consider.
    73  */
    74 static int isWatcomPassThruOption(const char *pszArg)
    75 {
    76     char ch = *pszArg++;
    77     if (ch != '-' && ch != '/')
    78         return 0;
    79     ch = *pszArg++;
    80     switch (ch)
    81     {
    82         /* Example: -d+VAR="string-value" */
    83         case 'd':
    84             if (ch == '+')
    85                 ch = *pszArg++;
    86             if (!isalpha(ch) && ch != '_')
    87                 return 0;
    88             return 1;
    89 
    90         default:
    91             return 0;
    92     }
    93 }
    94 
    95 
    96 /**
    97  * Replaces arguments in need of quoting.
    98  *
    99  * This will "leak" the original and/or the replacement string, depending on
    100  * how you look at it.
    101  *
    102  * For details on how MSC parses the command line, see "Parsing C Command-Line
    103  * Arguments": http://msdn.microsoft.com/en-us/library/a1y7w461.aspx
    104  *
    105  * @param   argc                The argument count.
    106  * @param   argv                The argument vector.
    107  * @param   fWatcomBrainDamage  Set if we're catering for wcc, wcc386 or similar
    108  *                              OpenWatcom tools.  They seem to follow some
    109  *                              ancient or home made quoting convention.
    110  * @param   pStdErr             For verbose debug info.
    111  */
    112 static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage, FILE *pStdErr)
    113 {
    114     int i;
    115     for (i = 0; i < argc; i++)
    116     {
    117         const char *pszOrgOrg = argv[i];
    118         const char *pszOrg    = pszOrgOrg;
    119         size_t      cchOrg    = strlen(pszOrg);
    120         const char *pszQuotes = (const char *)memchr(pszOrg, '"', cchOrg);
    121         const char *pszProblem = NULL;
    122         if (   pszQuotes
    123             || cchOrg == 0
    124             || (pszProblem = (const char *)memchr(pszOrg, ' ',  cchOrg)) != NULL
    125             || (pszProblem = (const char *)memchr(pszOrg, '\t', cchOrg)) != NULL
    126             || (pszProblem = (const char *)memchr(pszOrg, '\n', cchOrg)) != NULL
    127             || (pszProblem = (const char *)memchr(pszOrg, '\r', cchOrg)) != NULL
    128             || (pszProblem = (const char *)memchr(pszOrg, '&',  cchOrg)) != NULL
    129             || (pszProblem = (const char *)memchr(pszOrg, '>',  cchOrg)) != NULL
    130             || (pszProblem = (const char *)memchr(pszOrg, '<',  cchOrg)) != NULL
    131             || (pszProblem = (const char *)memchr(pszOrg, '|',  cchOrg)) != NULL
    132             || (pszProblem = (const char *)memchr(pszOrg, '%',  cchOrg)) != NULL
    133             || (pszProblem = (const char *)memchr(pszOrg, '\'', cchOrg)) != NULL
    134             || (   !fWatcomBrainDamage
    135                 && (pszProblem = (const char *)memchr(pszOrg, '=',  cchOrg)) != NULL)
    136             )
    137         {
    138             char   ch;
    139             int    fComplicated = pszQuotes || (cchOrg > 0 && pszOrg[cchOrg - 1] == '\\');
    140             size_t cchNew       = fComplicated ? cchOrg * 2 + 2 : cchOrg + 2;
    141             char  *pszNew       = (char *)malloc(cchNew + 1 /*term*/ + 3 /*passthru hack*/);
    142 
    143             argv[i] = pszNew;
    144 
    145             /* Watcom does not grok stuff like "-i=c:\program files\watcom\h",
    146                it think it's a source specification. In that case the quote
    147                must follow the equal sign. */
    148             if (fWatcomBrainDamage)
    149             {
    150                 size_t cchUnquoted  = 0;
    151                 if (pszOrg[0] == '@') /* Response file quoting: @"file name.rsp" */
    152                     cchUnquoted = 1;
    153                 else if (pszOrg[0] == '-' || pszOrg[0] == '/') /* Switch quoting. */
    154                 {
    155                     if (isWatcomPassThruOption(pszOrg))
    156                         cchUnquoted = strlen(pszOrg) + 1;
    157                     else
    158                     {
    159                         const char *pszNeedQuoting = (const char *)memchr(pszOrg, '=', cchOrg); /* For -i=dir and similar. */
    160                         if (   pszNeedQuoting == NULL
    161                             || (uintptr_t)pszNeedQuoting > (uintptr_t)(pszProblem ? pszProblem : pszQuotes))
    162                             pszNeedQuoting = pszProblem ? pszProblem : pszQuotes;
    163                         else
    164                             pszNeedQuoting++;
    165                         cchUnquoted = pszNeedQuoting - pszOrg;
    166                     }
    167                 }
    168                 if (cchUnquoted)
    169                 {
    170                     memcpy(pszNew, pszOrg, cchUnquoted);
    171                     pszNew += cchUnquoted;
    172                     pszOrg += cchUnquoted;
    173                     cchOrg -= cchUnquoted;
    174                 }
    175             }
    176 
    177             *pszNew++ = '"';
    178             if (fComplicated)
    179             {
    180                 while ((ch = *pszOrg++) != '\0')
    181                 {
    182                     if (ch == '"')
    183                     {
    184                         *pszNew++ = '\\';
    185                         *pszNew++ = '"';
    186                     }
    187                     else if (ch == '\\')
    188                     {
    189                         /* Backslashes are a bit complicated, they depends on
    190                            whether a quotation mark follows them or not.  They
    191                            only require escaping if one does. */
    192                         unsigned cSlashes = 1;
    193                         while ((ch = *pszOrg) == '\\')
    194                         {
    195                             pszOrg++;
    196                             cSlashes++;
    197                         }
    198                         if (ch == '"' || ch == '\0') /* We put a " at the EOS. */
    199                         {
    200                             while (cSlashes-- > 0)
    201                             {
    202                                 *pszNew++ = '\\';
    203                                 *pszNew++ = '\\';
    204                             }
    205                         }
    206                         else
    207                             while (cSlashes-- > 0)
    208                                 *pszNew++ = '\\';
    209                     }
    210                     else
    211                         *pszNew++ = ch;
    212                 }
    213             }
    214             else
    215             {
    216                 memcpy(pszNew, pszOrg, cchOrg);
    217                 pszNew += cchOrg;
    218             }
    219             *pszNew++ = '"';
    220             *pszNew = '\0';
    221         }
    222 
    223         if (g_cVerbosity > 0)
    224         {
    225             if (argv[i] == pszOrgOrg)
    226                 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, pszOrgOrg);
    227             else
    228             {
    229                 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, argv[i]);
    230                 fprintf(pStdErr, "kmk_redirect: debug:(orig[%i]=%s<eos>)\n", i, pszOrgOrg);
    231             }
    232         }
    233     }
    234 
    235     /*for (i = 0; i < argc; i++) fprintf(stderr, "argv[%u]=%s;;\n", i, argv[i]);*/
    236 }
    23765
    23866
     
    318146{
    319147    int i;
     148    int j;
    320149#if defined(_MSC_VER)
    321150    intptr_t rc;
    322 #else
    323     int j;
    324151#endif
    325152    FILE *pStdErr = stderr;
     
    824651
    825652    /* MSC is a PITA since it refuses to quote the arguments... */
    826     quoteArguments(argc - i, &argv[i], fWatcomBrainDamage, pStdErr);
     653    quote_argv(argc - i, &argv[i], fWatcomBrainDamage, 0 /*fFreeOrLeak*/);
     654    if (g_cVerbosity > 0)
     655        for (j = i; j < argc; j++)
     656            fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", j - i, argv[j]);
    827657    rc = _spawnvp(_P_WAIT, argv[i], &argv[i]);
    828658    if (rc == -1 && pStdErr)
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