15 #define _CRT_SECURE_NO_DEPRECATE 17 #define NO_SHLWAPI_GDI 18 #define NO_SHLWAPI_STREAM 19 #define NO_SHLWAPI_REG 21 #pragma comment (lib, "user32.lib") 22 #pragma comment (lib, "kernel32.lib") 23 #pragma comment (lib, "shlwapi.lib") 30 #if defined(_M_IA64) || defined(_M_AMD64) 31 #if _MSC_VER >= 1400 && _MSC_VER < 1500 32 #pragma comment(lib, "bufferoverflowU") 38 #define snprintf _snprintf 47 static int IsIn(
const char *
string,
const char *substring);
48 static int SubstituteFile(
const char *substs,
const char *filename);
56 #define STATICBUFFERSIZE 1000 82 SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
88 SetEnvironmentVariable(
"CL",
"");
89 SetEnvironmentVariable(
"LINK",
"");
91 if (argc > 1 && *argv[1] ==
'-') {
92 switch (*(argv[1]+1)) {
95 chars = snprintf(msg,
sizeof(msg) - 1,
96 "usage: %s -c <compiler option>\n" 97 "Tests for whether cl.exe supports an option\n" 98 "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
99 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
106 chars = snprintf(msg,
sizeof(msg) - 1,
107 "usage: %s -l <linker option>\n" 108 "Tests for whether link.exe supports an option\n" 109 "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
110 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
117 chars = snprintf(msg,
sizeof(msg) - 1,
118 "usage: %s -f <string> <substring>\n" 119 "Find a substring within another\n" 120 "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
121 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
124 }
else if (argc == 3) {
131 return IsIn(argv[2], argv[3]);
135 chars = snprintf(msg,
sizeof(msg) - 1,
136 "usage: %s -s <substitutions file> <file>\n" 137 "Perform a set of string map type substutitions on a file\n" 140 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
147 chars = snprintf(msg,
sizeof(msg) - 1,
148 "usage: %s -V filename matchstring\n" 149 "Extract a version from a file:\n" 150 "eg: pkgIndex.tcl \"package ifneeded http\"",
152 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
160 chars = snprintf(msg,
sizeof(msg) - 1,
161 "usage: %s -Q path\n" 162 "Emit the fully qualified path\n" 163 "exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
164 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
171 chars = snprintf(msg,
sizeof(msg) - 1,
172 "usage: %s -c|-f|-l|-Q|-s|-V ...\n" 173 "This is a little helper app to equalize shell differences between WinNT and\n" 174 "Win9x and get nmake.exe to accomplish its job.\n",
176 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
185 PROCESS_INFORMATION pi;
186 SECURITY_ATTRIBUTES sa;
190 HANDLE hProcess, h, pipeThreads[2];
193 hProcess = GetCurrentProcess();
195 ZeroMemory(&pi,
sizeof(PROCESS_INFORMATION));
196 ZeroMemory(&si,
sizeof(STARTUPINFO));
197 si.cb =
sizeof(STARTUPINFO);
198 si.dwFlags = STARTF_USESTDHANDLES;
199 si.hStdInput = INVALID_HANDLE_VALUE;
201 ZeroMemory(&sa,
sizeof(SECURITY_ATTRIBUTES));
202 sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
203 sa.lpSecurityDescriptor = NULL;
204 sa.bInheritHandle = FALSE;
210 CreatePipe(&Out.
pipe, &h, &sa, 0);
216 DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
217 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
223 CreatePipe(&Err.
pipe, &h, &sa, 0);
224 DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
225 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
231 lstrcpy(cmdline,
"cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
237 lstrcat(cmdline, option);
243 lstrcat(cmdline,
" .\\nul");
258 DWORD err = GetLastError();
259 int chars = snprintf(msg,
sizeof(msg) - 1,
260 "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
262 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
263 FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
265 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
273 CloseHandle(si.hStdOutput);
274 CloseHandle(si.hStdError);
276 WaitForInputIdle(pi.hProcess, 5000);
277 CloseHandle(pi.hThread);
283 pipeThreads[0] = CreateThread(NULL, 0,
ReadFromPipe, &Out, 0, &threadID);
284 pipeThreads[1] = CreateThread(NULL, 0,
ReadFromPipe, &Err, 0, &threadID);
290 WaitForSingleObject(pi.hProcess, INFINITE);
291 CloseHandle(pi.hProcess);
297 WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
298 CloseHandle(pipeThreads[0]);
299 CloseHandle(pipeThreads[1]);
306 return !(strstr(Out.
buffer,
"D4002") != NULL
307 || strstr(Err.
buffer,
"D4002") != NULL
308 || strstr(Out.
buffer,
"D9002") != NULL
309 || strstr(Err.
buffer,
"D9002") != NULL
310 || strstr(Out.
buffer,
"D2021") != NULL
311 || strstr(Err.
buffer,
"D2021") != NULL);
319 PROCESS_INFORMATION pi;
320 SECURITY_ATTRIBUTES sa;
324 HANDLE hProcess, h, pipeThreads[2];
327 hProcess = GetCurrentProcess();
329 ZeroMemory(&pi,
sizeof(PROCESS_INFORMATION));
330 ZeroMemory(&si,
sizeof(STARTUPINFO));
331 si.cb =
sizeof(STARTUPINFO);
332 si.dwFlags = STARTF_USESTDHANDLES;
333 si.hStdInput = INVALID_HANDLE_VALUE;
335 ZeroMemory(&sa,
sizeof(SECURITY_ATTRIBUTES));
336 sa.nLength =
sizeof(SECURITY_ATTRIBUTES);
337 sa.lpSecurityDescriptor = NULL;
338 sa.bInheritHandle = TRUE;
344 CreatePipe(&Out.
pipe, &h, &sa, 0);
350 DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
351 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
357 CreatePipe(&Err.
pipe, &h, &sa, 0);
358 DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
359 DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
365 lstrcpy(cmdline,
"link.exe -nologo ");
371 lstrcat(cmdline, option);
386 DWORD err = GetLastError();
387 int chars = snprintf(msg,
sizeof(msg) - 1,
388 "Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
390 FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
391 FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
393 WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
401 CloseHandle(si.hStdOutput);
402 CloseHandle(si.hStdError);
404 WaitForInputIdle(pi.hProcess, 5000);
405 CloseHandle(pi.hThread);
411 pipeThreads[0] = CreateThread(NULL, 0,
ReadFromPipe, &Out, 0, &threadID);
412 pipeThreads[1] = CreateThread(NULL, 0,
ReadFromPipe, &Err, 0, &threadID);
418 WaitForSingleObject(pi.hProcess, INFINITE);
419 CloseHandle(pi.hProcess);
425 WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
426 CloseHandle(pipeThreads[0]);
427 CloseHandle(pipeThreads[1]);
433 return !(strstr(Out.
buffer,
"LNK1117") != NULL ||
434 strstr(Err.
buffer,
"LNK1117") != NULL ||
435 strstr(Out.
buffer,
"LNK4044") != NULL ||
436 strstr(Err.
buffer,
"LNK4044") != NULL);
444 char *lastBuf = pi->
buffer;
450 CloseHandle(pi->
pipe);
453 ok = ReadFile(pi->
pipe, lastBuf,
CHUNK, &dwRead, 0L);
454 if (!ok || dwRead == 0) {
455 CloseHandle(pi->
pipe);
467 const char *substring)
469 return (strstr(
string, substring) != NULL);
481 const char *filename,
484 size_t cbBuffer = 100;
485 static char szBuffer[100];
486 char *szResult = NULL;
487 FILE *fp = fopen(filename,
"rt");
494 while (fgets(szBuffer, cbBuffer, fp) != NULL) {
497 p = strstr(szBuffer, match);
503 while (*p && !isdigit(*p)) {
512 while (*q && (isalnum(*q) || *q ==
'.')) {
516 memcpy(szBuffer, p, q - p);
543 itemPtr->
key = strdup(key);
544 itemPtr->
value = strdup(value);
548 listPtrPtr = &(*listPtrPtr)->
nextPtr;
550 *listPtrPtr = itemPtr;
587 const char *substitutions,
588 const char *filename)
590 size_t cbBuffer = 1024;
591 static char szBuffer[1024], szCopy[1024];
592 char *szResult = NULL;
596 fp = fopen(filename,
"rt");
603 sp = fopen(substitutions,
"rt");
605 while (fgets(szBuffer, cbBuffer, sp) != NULL) {
606 unsigned char *ks, *ke, *vs, *ve;
607 ks = (
unsigned char*)szBuffer;
608 while (ks && *ks && isspace(*ks)) ++ks;
610 while (ke && *ke && !isspace(*ke)) ++ke;
612 while (vs && *vs && isspace(*vs)) ++vs;
614 while (ve && *ve && !(*ve ==
'\r' || *ve ==
'\n')) ++ve;
626 for (p = substPtr; p != NULL; p = p->
nextPtr, ++n) {
627 fprintf(stderr,
"% 3d '%s' => '%s'\n", n, p->
key, p->
value);
636 while (fgets(szBuffer, cbBuffer, fp) != NULL) {
638 for (p = substPtr; p != NULL; p = p->
nextPtr) {
639 char *m = strstr(szBuffer, p->
key);
644 while (op != m) *cp++ = *op++;
646 while (sp && *sp) *cp++ = *sp++;
647 op += strlen(p->
key);
648 while (*op) *cp++ = *op++;
650 memcpy(szBuffer, szCopy,
sizeof(szCopy));
674 char szCwd[MAX_PATH + 1];
675 char szTmp[MAX_PATH + 1];
677 GetCurrentDirectory(MAX_PATH, szCwd);
678 while ((p = strchr(szPath,
'/')) && *p)
680 PathCombine(szTmp, szCwd, szPath);
681 PathCanonicalize(szCwd, szTmp);
682 printf(
"%s\n", szCwd);
static const char * GetVersionFromFile(const char *filename, const char *match)
static void list_free(list_item_t **listPtrPtr)
static int QualifyPath(const char *path)
static int CheckForLinkerFeature(const char *option)
static int CheckForCompilerFeature(const char *option)
static DWORD WINAPI ReadFromPipe(LPVOID args)
static int SubstituteFile(const char *substs, const char *filename)
static list_item_t * list_insert(list_item_t **listPtrPtr, const char *key, const char *value)
int main(int argc, char *argv[])
char buffer[STATICBUFFERSIZE]
struct list_item_t * nextPtr
static int IsIn(const char *string, const char *substring)
struct list_item_t list_item_t