- Timestamp:
- Mar 13, 2016 11:22:53 AM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/kmk/kmkbuiltin/redirect.c
r2779 r2812 5 5 6 6 /* 7 * Copyright (c) 2007-201 4knut st. osmundsen <[email protected]>7 * Copyright (c) 2007-2016 knut st. osmundsen <[email protected]> 8 8 * 9 9 * This file is part of kBuild. … … 34 34 #include <fcntl.h> 35 35 #if defined(_MSC_VER) 36 # include <ctype.h> 36 37 # include <io.h> 37 38 # include <direct.h> … … 50 51 51 52 53 /********************************************************************************************************************************* 54 * Global Variables * 55 *********************************************************************************************************************************/ 56 /** Number of times the '-v' switch was seen. */ 57 static unsigned g_cVerbosity = 0; 58 59 52 60 #if defined(_MSC_VER) 61 62 /** 63 * Checks if this is an Watcom option where we must just pass thru the string 64 * as-is. 65 * 66 * This is currnetly only used for -d (defining macros). 67 * 68 * @returns 1 if pass-thru, 0 if not. 69 * @param pszArg The argument to consider. 70 */ 71 static int isWatcomPassThruOption(const char *pszArg) 72 { 73 char ch = *pszArg++; 74 if (ch != '-' && ch != '/') 75 return 0; 76 ch = *pszArg++; 77 switch (ch) 78 { 79 /* Example: -d+VAR="string-value" */ 80 case 'd': 81 if (ch == '+') 82 ch = *pszArg++; 83 if (!isalpha(ch) && ch != '_') 84 return 0; 85 return 1; 86 87 default: 88 return 0; 89 } 90 } 91 92 53 93 /** 54 94 * Replaces arguments in need of quoting. … … 65 105 * OpenWatcom tools. They seem to follow some 66 106 * ancient or home made quoting convention. 107 * @param pStdErr For verbose debug info. 67 108 */ 68 static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage )109 static void quoteArguments(int argc, char **argv, int fWatcomBrainDamage, FILE *pStdErr) 69 110 { 70 111 int i; 71 112 for (i = 0; i < argc; i++) 72 113 { 73 const char *pszOrg = argv[i]; 114 const char *pszOrgOrg = argv[i]; 115 const char *pszOrg = pszOrgOrg; 74 116 size_t cchOrg = strlen(pszOrg); 75 117 const char *pszQuotes = (const char *)memchr(pszOrg, '"', cchOrg); … … 94 136 int fComplicated = pszQuotes || (cchOrg > 0 && pszOrg[cchOrg - 1] == '\\'); 95 137 size_t cchNew = fComplicated ? cchOrg * 2 + 2 : cchOrg + 2; 96 char *pszNew = (char *)malloc(cchNew + 1 );138 char *pszNew = (char *)malloc(cchNew + 1 /*term*/ + 3 /*passthru hack*/); 97 139 98 140 argv[i] = pszNew; 99 141 100 /* Watcom does not grok "-i=c:\program files\watcom\h", it thing 101 it's a source specification. The quote must follow the equal. */ 142 /* Watcom does not grok stuff like "-i=c:\program files\watcom\h", 143 it think it's a source specification. In that case the quote 144 must follow the equal sign. */ 102 145 if (fWatcomBrainDamage) 103 146 { … … 107 150 else if (pszOrg[0] == '-' || pszOrg[0] == '/') /* Switch quoting. */ 108 151 { 109 const char *pszNeedQuoting = (const char *)memchr(pszOrg, '=', cchOrg); 110 if ( pszNeedQuoting == NULL 111 || (uintptr_t)pszNeedQuoting > (uintptr_t)(pszProblem ? pszProblem : pszQuotes)) 112 pszNeedQuoting = pszProblem ? pszProblem : pszQuotes; 152 if (isWatcomPassThruOption(pszOrg)) 153 cchUnquoted = strlen(pszOrg) + 1; 113 154 else 114 pszNeedQuoting++; 115 cchUnquoted = pszNeedQuoting - pszOrg; 155 { 156 const char *pszNeedQuoting = (const char *)memchr(pszOrg, '=', cchOrg); /* For -i=dir and similar. */ 157 if ( pszNeedQuoting == NULL 158 || (uintptr_t)pszNeedQuoting > (uintptr_t)(pszProblem ? pszProblem : pszQuotes)) 159 pszNeedQuoting = pszProblem ? pszProblem : pszQuotes; 160 else 161 pszNeedQuoting++; 162 cchUnquoted = pszNeedQuoting - pszOrg; 163 } 116 164 } 117 165 if (cchUnquoted) … … 169 217 *pszNew = '\0'; 170 218 } 219 220 if (g_cVerbosity > 0) 221 { 222 if (argv[i] == pszOrgOrg) 223 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, pszOrgOrg); 224 else 225 { 226 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", i, argv[i]); 227 fprintf(pStdErr, "kmk_redirect: debug:(orig[%i]=%s<eos>)\n", i, pszOrgOrg); 228 } 229 } 171 230 } 172 231 173 232 /*for (i = 0; i < argc; i++) fprintf(stderr, "argv[%u]=%s;;\n", i, argv[i]);*/ 174 233 } 175 #endif /* _MSC_VER */ 176 177 178 #ifdef _MSC_VER 234 235 179 236 /** Used by safeCloseFd. */ 180 237 static void __cdecl ignore_invalid_parameter(const wchar_t *a, const wchar_t *b, const wchar_t *c, unsigned d, uintptr_t e) 181 238 { 182 239 } 183 #endif 240 241 #endif /* _MSC_VER */ 184 242 185 243 … … 219 277 { 220 278 fprintf(pOut, 221 "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage] -- <program> [args]\n"279 "usage: %s [-[rwa+tb]<fd> <file>] [-c<fd>] [-Z] [-E <var=val>] [-C <dir>] [--wcc-brain-damage] [-v] -- <program> [args]\n" 222 280 " or: %s --help\n" 223 281 " or: %s --version\n" … … 242 300 "not following normal quoting conventions on Windows, OS/2, and DOS.\n" 243 301 "\n" 302 "The -v switch is for making the thing more verbose.\n" 303 "\n" 244 304 "This command was originally just a quick hack to avoid invoking the shell\n" 245 305 "on Windows (cygwin) where forking is very expensive and has exhibited\n" … … 257 317 #if defined(_MSC_VER) 258 318 intptr_t rc; 319 #else 320 int j; 259 321 #endif 260 322 FILE *pStdErr = stderr; … … 470 532 471 533 /* 534 * Verbose operation switch? 535 */ 536 if (*psz == 'v') 537 { 538 g_cVerbosity++; 539 continue; 540 } 541 542 /* 472 543 * Close the specified file descriptor (no stderr/out/in aliases). 473 544 */ … … 750 821 751 822 /* MSC is a PITA since it refuses to quote the arguments... */ 752 quoteArguments(argc - i, &argv[i], fWatcomBrainDamage );823 quoteArguments(argc - i, &argv[i], fWatcomBrainDamage, pStdErr); 753 824 rc = _spawnvp(_P_WAIT, argv[i], &argv[i]); 754 825 if (rc == -1 && pStdErr) … … 759 830 return rc; 760 831 #else 832 if (g_cVerbosity > 0) 833 for (j = i; j < argc; j++) 834 fprintf(pStdErr, "kmk_redirect: debug: argv[%i]=%s<eos>\n", j - i, argv[j]); 761 835 execvp(argv[i], &argv[i]); 762 836 fprintf(pStdErr, "%s: error: _execvp(_P_WAIT, \"%s\", ...) failed: %s\n", name(argv[0]), argv[i], strerror(errno));
Note:
See TracChangeset
for help on using the changeset viewer.