os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/win/nmakehlp.c
changeset 0 bde4ae8d615e
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/os/persistentdata/persistentstorage/sqlite3api/TEST/TCL/tcldistribution/win/nmakehlp.c	Fri Jun 15 03:10:57 2012 +0200
     1.3 @@ -0,0 +1,490 @@
     1.4 +/*
     1.5 + * ----------------------------------------------------------------------------
     1.6 + * nmakehlp.c --
     1.7 + *
     1.8 + *	This is used to fix limitations within nmake and the environment.
     1.9 + *
    1.10 + * Copyright (c) 2002 by David Gravereaux.
    1.11 + *
    1.12 + * See the file "license.terms" for information on usage and redistribution
    1.13 + * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
    1.14 + *
    1.15 + * ----------------------------------------------------------------------------
    1.16 + * RCS: @(#) $Id: nmakehlp.c,v 1.1.4.4 2006/10/18 08:49:33 patthoyts Exp $
    1.17 + * ----------------------------------------------------------------------------
    1.18 + */
    1.19 +
    1.20 +#define _CRT_SECURE_NO_DEPRECATE
    1.21 +#include <windows.h>
    1.22 +#pragma comment (lib, "user32.lib")
    1.23 +#pragma comment (lib, "kernel32.lib")
    1.24 +#include <stdio.h>
    1.25 +#include <math.h>
    1.26 +#if defined(_M_IA64) || defined(_M_AMD64)
    1.27 +#pragma comment(lib, "bufferoverflowU")
    1.28 +#endif
    1.29 +
    1.30 +/* ISO hack for dumb VC++ */
    1.31 +#ifdef _MSC_VER
    1.32 +#define   snprintf	_snprintf
    1.33 +#endif
    1.34 +
    1.35 +
    1.36 +
    1.37 +/* protos */
    1.38 +
    1.39 +int		CheckForCompilerFeature(const char *option);
    1.40 +int		CheckForLinkerFeature(const char *option);
    1.41 +int		IsIn(const char *string, const char *substring);
    1.42 +int		GrepForDefine(const char *file, const char *string);
    1.43 +DWORD WINAPI	ReadFromPipe(LPVOID args);
    1.44 +
    1.45 +/* globals */
    1.46 +
    1.47 +#define CHUNK	25
    1.48 +#define STATICBUFFERSIZE    1000
    1.49 +typedef struct {
    1.50 +    HANDLE pipe;
    1.51 +    char buffer[STATICBUFFERSIZE];
    1.52 +} pipeinfo;
    1.53 +
    1.54 +pipeinfo Out = {INVALID_HANDLE_VALUE, '\0'};
    1.55 +pipeinfo Err = {INVALID_HANDLE_VALUE, '\0'};
    1.56 +
    1.57 +/*
    1.58 + * exitcodes: 0 == no, 1 == yes, 2 == error
    1.59 + */
    1.60 +
    1.61 +int
    1.62 +main(
    1.63 +    int argc,
    1.64 +    char *argv[])
    1.65 +{
    1.66 +    char msg[300];
    1.67 +    DWORD dwWritten;
    1.68 +    int chars;
    1.69 +
    1.70 +    /*
    1.71 +     * Make sure children (cl.exe and link.exe) are kept quiet.
    1.72 +     */
    1.73 +
    1.74 +    SetErrorMode(SEM_FAILCRITICALERRORS | SEM_NOOPENFILEERRORBOX);
    1.75 +
    1.76 +    /*
    1.77 +     * Make sure the compiler and linker aren't effected by the outside world.
    1.78 +     */
    1.79 +
    1.80 +    SetEnvironmentVariable("CL", "");
    1.81 +    SetEnvironmentVariable("LINK", "");
    1.82 +
    1.83 +    if (argc > 1 && *argv[1] == '-') {
    1.84 +	switch (*(argv[1]+1)) {
    1.85 +	case 'c':
    1.86 +	    if (argc != 3) {
    1.87 +		chars = snprintf(msg, sizeof(msg) - 1,
    1.88 +		        "usage: %s -c <compiler option>\n"
    1.89 +			"Tests for whether cl.exe supports an option\n"
    1.90 +			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
    1.91 +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
    1.92 +			&dwWritten, NULL);
    1.93 +		return 2;
    1.94 +	    }
    1.95 +	    return CheckForCompilerFeature(argv[2]);
    1.96 +	case 'l':
    1.97 +	    if (argc != 3) {
    1.98 +		chars = snprintf(msg, sizeof(msg) - 1,
    1.99 +	       		"usage: %s -l <linker option>\n"
   1.100 +			"Tests for whether link.exe supports an option\n"
   1.101 +			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   1.102 +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   1.103 +			&dwWritten, NULL);
   1.104 +		return 2;
   1.105 +	    }
   1.106 +	    return CheckForLinkerFeature(argv[2]);
   1.107 +	case 'f':
   1.108 +	    if (argc == 2) {
   1.109 +		chars = snprintf(msg, sizeof(msg) - 1,
   1.110 +			"usage: %s -f <string> <substring>\n"
   1.111 +			"Find a substring within another\n"
   1.112 +			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
   1.113 +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   1.114 +			&dwWritten, NULL);
   1.115 +		return 2;
   1.116 +	    } else if (argc == 3) {
   1.117 +		/*
   1.118 +		 * If the string is blank, there is no match.
   1.119 +		 */
   1.120 +
   1.121 +		return 0;
   1.122 +	    } else {
   1.123 +		return IsIn(argv[2], argv[3]);
   1.124 +	    }
   1.125 +	case 'g':
   1.126 +	    if (argc == 2) {
   1.127 +		chars = snprintf(msg, sizeof(msg) - 1,
   1.128 +			"usage: %s -g <file> <string>\n"
   1.129 +			"grep for a #define\n"
   1.130 +			"exitcodes: integer of the found string (no decimals)\n",
   1.131 +			argv[0]);
   1.132 +		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
   1.133 +			&dwWritten, NULL);
   1.134 +		return 2;
   1.135 +	    }
   1.136 +	    return GrepForDefine(argv[2], argv[3]);
   1.137 +	}
   1.138 +    }
   1.139 +    chars = snprintf(msg, sizeof(msg) - 1,
   1.140 +	    "usage: %s -c|-l|-f ...\n"
   1.141 +	    "This is a little helper app to equalize shell differences between WinNT and\n"
   1.142 +	    "Win9x and get nmake.exe to accomplish its job.\n",
   1.143 +	    argv[0]);
   1.144 +    WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars, &dwWritten, NULL);
   1.145 +    return 2;
   1.146 +}
   1.147 +
   1.148 +int
   1.149 +CheckForCompilerFeature(
   1.150 +    const char *option)
   1.151 +{
   1.152 +    STARTUPINFO si;
   1.153 +    PROCESS_INFORMATION pi;
   1.154 +    SECURITY_ATTRIBUTES sa;
   1.155 +    DWORD threadID;
   1.156 +    char msg[300];
   1.157 +    BOOL ok;
   1.158 +    HANDLE hProcess, h, pipeThreads[2];
   1.159 +    char cmdline[100];
   1.160 +
   1.161 +    hProcess = GetCurrentProcess();
   1.162 +
   1.163 +    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
   1.164 +    ZeroMemory(&si, sizeof(STARTUPINFO));
   1.165 +    si.cb = sizeof(STARTUPINFO);
   1.166 +    si.dwFlags   = STARTF_USESTDHANDLES;
   1.167 +    si.hStdInput = INVALID_HANDLE_VALUE;
   1.168 +
   1.169 +    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
   1.170 +    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
   1.171 +    sa.lpSecurityDescriptor = NULL;
   1.172 +    sa.bInheritHandle = FALSE;
   1.173 +
   1.174 +    /*
   1.175 +     * Create a non-inheritible pipe.
   1.176 +     */
   1.177 +
   1.178 +    CreatePipe(&Out.pipe, &h, &sa, 0);
   1.179 +
   1.180 +    /*
   1.181 +     * Dupe the write side, make it inheritible, and close the original.
   1.182 +     */
   1.183 +
   1.184 +    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
   1.185 +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
   1.186 +
   1.187 +    /*
   1.188 +     * Same as above, but for the error side.
   1.189 +     */
   1.190 +
   1.191 +    CreatePipe(&Err.pipe, &h, &sa, 0);
   1.192 +    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
   1.193 +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
   1.194 +
   1.195 +    /*
   1.196 +     * Base command line.
   1.197 +     */
   1.198 +
   1.199 +    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X ");
   1.200 +
   1.201 +    /*
   1.202 +     * Append our option for testing
   1.203 +     */
   1.204 +
   1.205 +    lstrcat(cmdline, option);
   1.206 +
   1.207 +    /*
   1.208 +     * Filename to compile, which exists, but is nothing and empty.
   1.209 +     */
   1.210 +
   1.211 +    lstrcat(cmdline, " .\\nul");
   1.212 +
   1.213 +    ok = CreateProcess(
   1.214 +	    NULL,	    /* Module name. */
   1.215 +	    cmdline,	    /* Command line. */
   1.216 +	    NULL,	    /* Process handle not inheritable. */
   1.217 +	    NULL,	    /* Thread handle not inheritable. */
   1.218 +	    TRUE,	    /* yes, inherit handles. */
   1.219 +	    DETACHED_PROCESS, /* No console for you. */
   1.220 +	    NULL,	    /* Use parent's environment block. */
   1.221 +	    NULL,	    /* Use parent's starting directory. */
   1.222 +	    &si,	    /* Pointer to STARTUPINFO structure. */
   1.223 +	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
   1.224 +
   1.225 +    if (!ok) {
   1.226 +	DWORD err = GetLastError();
   1.227 +	int chars = snprintf(msg, sizeof(msg) - 1,
   1.228 +		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   1.229 +
   1.230 +	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
   1.231 +		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   1.232 +		(300-chars), 0);
   1.233 +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
   1.234 +	return 2;
   1.235 +    }
   1.236 +
   1.237 +    /*
   1.238 +     * Close our references to the write handles that have now been inherited.
   1.239 +     */
   1.240 +
   1.241 +    CloseHandle(si.hStdOutput);
   1.242 +    CloseHandle(si.hStdError);
   1.243 +
   1.244 +    WaitForInputIdle(pi.hProcess, 5000);
   1.245 +    CloseHandle(pi.hThread);
   1.246 +
   1.247 +    /*
   1.248 +     * Start the pipe reader threads.
   1.249 +     */
   1.250 +
   1.251 +    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
   1.252 +    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
   1.253 +
   1.254 +    /*
   1.255 +     * Block waiting for the process to end.
   1.256 +     */
   1.257 +
   1.258 +    WaitForSingleObject(pi.hProcess, INFINITE);
   1.259 +    CloseHandle(pi.hProcess);
   1.260 +
   1.261 +    /*
   1.262 +     * Wait for our pipe to get done reading, should it be a little slow.
   1.263 +     */
   1.264 +
   1.265 +    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
   1.266 +    CloseHandle(pipeThreads[0]);
   1.267 +    CloseHandle(pipeThreads[1]);
   1.268 +
   1.269 +    /*
   1.270 +     * Look for the commandline warning code in both streams.
   1.271 +     *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
   1.272 +     */
   1.273 +
   1.274 +    return !(strstr(Out.buffer, "D4002") != NULL
   1.275 +             || strstr(Err.buffer, "D4002") != NULL
   1.276 +             || strstr(Out.buffer, "D9002") != NULL
   1.277 +             || strstr(Err.buffer, "D9002") != NULL);
   1.278 +}
   1.279 +
   1.280 +int
   1.281 +CheckForLinkerFeature(
   1.282 +    const char *option)
   1.283 +{
   1.284 +    STARTUPINFO si;
   1.285 +    PROCESS_INFORMATION pi;
   1.286 +    SECURITY_ATTRIBUTES sa;
   1.287 +    DWORD threadID;
   1.288 +    char msg[300];
   1.289 +    BOOL ok;
   1.290 +    HANDLE hProcess, h, pipeThreads[2];
   1.291 +    char cmdline[100];
   1.292 +
   1.293 +    hProcess = GetCurrentProcess();
   1.294 +
   1.295 +    ZeroMemory(&pi, sizeof(PROCESS_INFORMATION));
   1.296 +    ZeroMemory(&si, sizeof(STARTUPINFO));
   1.297 +    si.cb = sizeof(STARTUPINFO);
   1.298 +    si.dwFlags   = STARTF_USESTDHANDLES;
   1.299 +    si.hStdInput = INVALID_HANDLE_VALUE;
   1.300 +
   1.301 +    ZeroMemory(&sa, sizeof(SECURITY_ATTRIBUTES));
   1.302 +    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
   1.303 +    sa.lpSecurityDescriptor = NULL;
   1.304 +    sa.bInheritHandle = TRUE;
   1.305 +
   1.306 +    /*
   1.307 +     * Create a non-inheritible pipe.
   1.308 +     */
   1.309 +
   1.310 +    CreatePipe(&Out.pipe, &h, &sa, 0);
   1.311 +
   1.312 +    /*
   1.313 +     * Dupe the write side, make it inheritible, and close the original.
   1.314 +     */
   1.315 +
   1.316 +    DuplicateHandle(hProcess, h, hProcess, &si.hStdOutput, 0, TRUE,
   1.317 +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
   1.318 +
   1.319 +    /*
   1.320 +     * Same as above, but for the error side.
   1.321 +     */
   1.322 +
   1.323 +    CreatePipe(&Err.pipe, &h, &sa, 0);
   1.324 +    DuplicateHandle(hProcess, h, hProcess, &si.hStdError, 0, TRUE,
   1.325 +	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
   1.326 +
   1.327 +    /*
   1.328 +     * Base command line.
   1.329 +     */
   1.330 +
   1.331 +    lstrcpy(cmdline, "link.exe -nologo ");
   1.332 +
   1.333 +    /*
   1.334 +     * Append our option for testing.
   1.335 +     */
   1.336 +
   1.337 +    lstrcat(cmdline, option);
   1.338 +
   1.339 +    ok = CreateProcess(
   1.340 +	    NULL,	    /* Module name. */
   1.341 +	    cmdline,	    /* Command line. */
   1.342 +	    NULL,	    /* Process handle not inheritable. */
   1.343 +	    NULL,	    /* Thread handle not inheritable. */
   1.344 +	    TRUE,	    /* yes, inherit handles. */
   1.345 +	    DETACHED_PROCESS, /* No console for you. */
   1.346 +	    NULL,	    /* Use parent's environment block. */
   1.347 +	    NULL,	    /* Use parent's starting directory. */
   1.348 +	    &si,	    /* Pointer to STARTUPINFO structure. */
   1.349 +	    &pi);	    /* Pointer to PROCESS_INFORMATION structure. */
   1.350 +
   1.351 +    if (!ok) {
   1.352 +	DWORD err = GetLastError();
   1.353 +	int chars = snprintf(msg, sizeof(msg) - 1,
   1.354 +		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
   1.355 +
   1.356 +	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
   1.357 +		FORMAT_MESSAGE_MAX_WIDTH_MASK, 0L, err, 0, (LPVOID)&msg[chars],
   1.358 +		(300-chars), 0);
   1.359 +	WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, lstrlen(msg), &err,NULL);
   1.360 +	return 2;
   1.361 +    }
   1.362 +
   1.363 +    /*
   1.364 +     * Close our references to the write handles that have now been inherited.
   1.365 +     */
   1.366 +
   1.367 +    CloseHandle(si.hStdOutput);
   1.368 +    CloseHandle(si.hStdError);
   1.369 +
   1.370 +    WaitForInputIdle(pi.hProcess, 5000);
   1.371 +    CloseHandle(pi.hThread);
   1.372 +
   1.373 +    /*
   1.374 +     * Start the pipe reader threads.
   1.375 +     */
   1.376 +
   1.377 +    pipeThreads[0] = CreateThread(NULL, 0, ReadFromPipe, &Out, 0, &threadID);
   1.378 +    pipeThreads[1] = CreateThread(NULL, 0, ReadFromPipe, &Err, 0, &threadID);
   1.379 +
   1.380 +    /*
   1.381 +     * Block waiting for the process to end.
   1.382 +     */
   1.383 +
   1.384 +    WaitForSingleObject(pi.hProcess, INFINITE);
   1.385 +    CloseHandle(pi.hProcess);
   1.386 +
   1.387 +    /*
   1.388 +     * Wait for our pipe to get done reading, should it be a little slow.
   1.389 +     */
   1.390 +
   1.391 +    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
   1.392 +    CloseHandle(pipeThreads[0]);
   1.393 +    CloseHandle(pipeThreads[1]);
   1.394 +
   1.395 +    /*
   1.396 +     * Look for the commandline warning code in the stderr stream.
   1.397 +     */
   1.398 +
   1.399 +    return !(strstr(Out.buffer, "LNK1117") != NULL ||
   1.400 +             strstr(Err.buffer, "LNK1117") != NULL ||
   1.401 +             strstr(Out.buffer, "LNK4044") != NULL ||
   1.402 +             strstr(Err.buffer, "LNK4044") != NULL);
   1.403 +}
   1.404 +
   1.405 +DWORD WINAPI
   1.406 +ReadFromPipe(
   1.407 +    LPVOID args)
   1.408 +{
   1.409 +    pipeinfo *pi = (pipeinfo *) args;
   1.410 +    char *lastBuf = pi->buffer;
   1.411 +    DWORD dwRead;
   1.412 +    BOOL ok;
   1.413 +
   1.414 +  again:
   1.415 +    if (lastBuf - pi->buffer + CHUNK > STATICBUFFERSIZE) {
   1.416 +	CloseHandle(pi->pipe);
   1.417 +	return (DWORD)-1;
   1.418 +    }
   1.419 +    ok = ReadFile(pi->pipe, lastBuf, CHUNK, &dwRead, 0L);
   1.420 +    if (!ok || dwRead == 0) {
   1.421 +	CloseHandle(pi->pipe);
   1.422 +	return 0;
   1.423 +    }
   1.424 +    lastBuf += dwRead;
   1.425 +    goto again;
   1.426 +
   1.427 +    return 0;  /* makes the compiler happy */
   1.428 +}
   1.429 +
   1.430 +int
   1.431 +IsIn(
   1.432 +    const char *string,
   1.433 +    const char *substring)
   1.434 +{
   1.435 +    return (strstr(string, substring) != NULL);
   1.436 +}
   1.437 +
   1.438 +/*
   1.439 + * Find a specified #define by name.
   1.440 + *
   1.441 + * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
   1.442 + */
   1.443 +
   1.444 +int
   1.445 +GrepForDefine(
   1.446 +    const char *file,
   1.447 +    const char *string)
   1.448 +{
   1.449 +    FILE *f;
   1.450 +    char s1[51], s2[51], s3[51];
   1.451 +    int r = 0;
   1.452 +    double d1;
   1.453 +
   1.454 +    f = fopen(file, "rt");
   1.455 +    if (f == NULL) {
   1.456 +	return 0;
   1.457 +    }
   1.458 +
   1.459 +    do {
   1.460 +	r = fscanf(f, "%50s", s1);
   1.461 +	if (r == 1 && !strcmp(s1, "#define")) {
   1.462 +	    /*
   1.463 +	     * Get next two words.
   1.464 +	     */
   1.465 +
   1.466 +	    r = fscanf(f, "%50s %50s", s2, s3);
   1.467 +	    if (r != 2) {
   1.468 +		continue;
   1.469 +	    }
   1.470 +
   1.471 +	    /*
   1.472 +	     * Is the first word what we're looking for?
   1.473 +	     */
   1.474 +
   1.475 +	    if (!strcmp(s2, string)) {
   1.476 +		fclose(f);
   1.477 +
   1.478 +		/*
   1.479 +		 * Add 1 past first double quote char. "8.5"
   1.480 +		 */
   1.481 +
   1.482 +		d1 = atof(s3 + 1);		  /*    8.5  */
   1.483 +		while (floor(d1) != d1) {
   1.484 +		    d1 *= 10.0;
   1.485 +		}
   1.486 +		return ((int) d1);		  /*    85   */
   1.487 +	    }
   1.488 +	}
   1.489 +    } while (!feof(f));
   1.490 +
   1.491 +    fclose(f);
   1.492 +    return 0;
   1.493 +}