Changeset 2839 in kBuild for trunk/src/kmk/kmkbuiltin/redirect.c
- Timestamp:
- Aug 25, 2016 9:46:44 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/redirect.c
r2822 r2839 41 41 # include <direct.h> 42 42 # include <process.h> 43 # include "quote_argv.h" 43 44 #else 44 45 # include <unistd.h> … … 62 63 63 64 #if defined(_MSC_VER) 64 65 /**66 * Checks if this is an Watcom option where we must just pass thru the string67 * 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 on100 * how you look at it.101 *102 * For details on how MSC parses the command line, see "Parsing C Command-Line103 * Arguments": http://msdn.microsoft.com/en-us/library/a1y7w461.aspx104 *105 * @param argc The argument count.106 * @param argv The argument vector.107 * @param fWatcomBrainDamage Set if we're catering for wcc, wcc386 or similar108 * OpenWatcom tools. They seem to follow some109 * 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 ( pszQuotes123 || cchOrg == 0124 || (pszProblem = (const char *)memchr(pszOrg, ' ', cchOrg)) != NULL125 || (pszProblem = (const char *)memchr(pszOrg, '\t', cchOrg)) != NULL126 || (pszProblem = (const char *)memchr(pszOrg, '\n', cchOrg)) != NULL127 || (pszProblem = (const char *)memchr(pszOrg, '\r', cchOrg)) != NULL128 || (pszProblem = (const char *)memchr(pszOrg, '&', cchOrg)) != NULL129 || (pszProblem = (const char *)memchr(pszOrg, '>', cchOrg)) != NULL130 || (pszProblem = (const char *)memchr(pszOrg, '<', cchOrg)) != NULL131 || (pszProblem = (const char *)memchr(pszOrg, '|', cchOrg)) != NULL132 || (pszProblem = (const char *)memchr(pszOrg, '%', cchOrg)) != NULL133 || (pszProblem = (const char *)memchr(pszOrg, '\'', cchOrg)) != NULL134 || ( !fWatcomBrainDamage135 && (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 quote147 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 else158 {159 const char *pszNeedQuoting = (const char *)memchr(pszOrg, '=', cchOrg); /* For -i=dir and similar. */160 if ( pszNeedQuoting == NULL161 || (uintptr_t)pszNeedQuoting > (uintptr_t)(pszProblem ? pszProblem : pszQuotes))162 pszNeedQuoting = pszProblem ? pszProblem : pszQuotes;163 else164 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 on190 whether a quotation mark follows them or not. They191 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 else207 while (cSlashes-- > 0)208 *pszNew++ = '\\';209 }210 else211 *pszNew++ = ch;212 }213 }214 else215 {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 else228 {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 }237 65 238 66 … … 318 146 { 319 147 int i; 148 int j; 320 149 #if defined(_MSC_VER) 321 150 intptr_t rc; 322 #else323 int j;324 151 #endif 325 152 FILE *pStdErr = stderr; … … 824 651 825 652 /* 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]); 827 657 rc = _spawnvp(_P_WAIT, argv[i], &argv[i]); 828 658 if (rc == -1 && pStdErr)
Note:
See TracChangeset
for help on using the changeset viewer.