Index: win/nmakehlp.c
===================================================================
RCS file: /cvsroot/tcl/sampleextension/win/nmakehlp.c,v
retrieving revision 1.4
diff -u -r1.4 nmakehlp.c
--- win/nmakehlp.c	8 Oct 2006 16:28:28 -0000	1.4
+++ win/nmakehlp.c	9 Feb 2007 06:43:00 -0000
@@ -1,37 +1,43 @@
-/* ----------------------------------------------------------------------------
+/*
+ * ----------------------------------------------------------------------------
  * nmakehlp.c --
  *
  *	This is used to fix limitations within nmake and the environment.
  *
  * Copyright (c) 2002 by David Gravereaux.
- * Copyright (c) 2003 by Patrick Thoyts
  *
  * See the file "license.terms" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
  * ----------------------------------------------------------------------------
- * RCS: @(#) $Id: nmakehlp.c,v 1.4 2006/10/08 16:28:28 patthoyts Exp $
+ * RCS: @(#) $Id: nmakehlp.c,v 1.15 2007/02/09 06:43:00 mistachkin Exp $
  * ----------------------------------------------------------------------------
  */
 
 #define _CRT_SECURE_NO_DEPRECATE
 #include <windows.h>
-#include <shlwapi.h>
 #pragma comment (lib, "user32.lib")
 #pragma comment (lib, "kernel32.lib")
-#pragma comment (lib, "shlwapi.lib")
 #include <stdio.h>
+#include <math.h>
 #if defined(_M_IA64) || defined(_M_AMD64)
 #pragma comment(lib, "bufferoverflowU")
 #endif
 
+/* ISO hack for dumb VC++ */
+#ifdef _MSC_VER
+#define   snprintf	_snprintf
+#endif
+
+
+
 /* protos */
 
 int		CheckForCompilerFeature(const char *option);
 int		CheckForLinkerFeature(const char *option);
 int		IsIn(const char *string, const char *substring);
 int		GrepForDefine(const char *file, const char *string);
-int		GetVersionFromHeader(const char *tclh, const char *tkh);
+const char *    GetVersionFromFile(const char *filename, const char *match);
 DWORD WINAPI	ReadFromPipe(LPVOID args);
 
 /* globals */
@@ -51,7 +57,9 @@
  */
 
 int
-main (int argc, char *argv[])
+main(
+    int argc,
+    char *argv[])
 {
     char msg[300];
     DWORD dwWritten;
@@ -74,7 +82,7 @@
 	switch (*(argv[1]+1)) {
 	case 'c':
 	    if (argc != 3) {
-		chars = wnsprintf(msg, sizeof(msg)-1,
+		chars = snprintf(msg, sizeof(msg) - 1,
 		        "usage: %s -c <compiler option>\n"
 			"Tests for whether cl.exe supports an option\n"
 			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
@@ -85,7 +93,7 @@
 	    return CheckForCompilerFeature(argv[2]);
 	case 'l':
 	    if (argc != 3) {
-		chars = wnsprintf(msg, sizeof(msg) - 1,
+		chars = snprintf(msg, sizeof(msg) - 1,
 	       		"usage: %s -l <linker option>\n"
 			"Tests for whether link.exe supports an option\n"
 			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
@@ -96,7 +104,7 @@
 	    return CheckForLinkerFeature(argv[2]);
 	case 'f':
 	    if (argc == 2) {
-		chars = wnsprintf(msg, sizeof(msg) - 1,
+		chars = snprintf(msg, sizeof(msg) - 1,
 			"usage: %s -f <string> <substring>\n"
 			"Find a substring within another\n"
 			"exitcodes: 0 == no, 1 == yes, 2 == error\n", argv[0]);
@@ -112,21 +120,35 @@
 	    } else {
 		return IsIn(argv[2], argv[3]);
 	    }
-	case 'v':
+	case 'g':
+	    if (argc == 2) {
+		chars = snprintf(msg, sizeof(msg) - 1,
+			"usage: %s -g <file> <string>\n"
+			"grep for a #define\n"
+			"exitcodes: integer of the found string (no decimals)\n",
+			argv[0]);
+		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
+			&dwWritten, NULL);
+		return 2;
+	    }
+	    return GrepForDefine(argv[2], argv[3]);
+	case 'V':
 	    if (argc != 4) {
-		chars = wnsprintf(msg, sizeof(msg) - 1,
-		    "usage: %s -v <tcl.h> <tk.h>\n"
-		    "Search for versions from the tcl and tk headers.",
+		chars = snprintf(msg, sizeof(msg) - 1,
+		    "usage: %s -V filename matchstring\n"
+		    "Extract a version from a file:\n"
+		    "eg: pkgIndex.tcl \"package ifneeded http\"",
 		    argv[0]);
 		WriteFile(GetStdHandle(STD_ERROR_HANDLE), msg, chars,
 		    &dwWritten, NULL);
 		return 0;
 	    }
-	    return GetVersionFromHeader(argv[2], argv[3]);
+	    printf("%s\n", GetVersionFromFile(argv[2], argv[3]));
+	    return 0;
 	}
     }
-    chars = wnsprintf(msg, sizeof(msg) - 1,
-	    "usage: %s -c|-l|-f ...\n"
+    chars = snprintf(msg, sizeof(msg) - 1,
+	    "usage: %s -c|-l|-f|-g|-V ...\n"
 	    "This is a little helper app to equalize shell differences between WinNT and\n"
 	    "Win9x and get nmake.exe to accomplish its job.\n",
 	    argv[0]);
@@ -141,11 +163,11 @@
     STARTUPINFO si;
     PROCESS_INFORMATION pi;
     SECURITY_ATTRIBUTES sa;
-    DWORD threadID, n;
+    DWORD threadID;
     char msg[300];
     BOOL ok;
     HANDLE hProcess, h, pipeThreads[2];
-    char cmdline[256];
+    char cmdline[100];
 
     hProcess = GetCurrentProcess();
 
@@ -182,15 +204,10 @@
 	    DUPLICATE_SAME_ACCESS | DUPLICATE_CLOSE_SOURCE);
 
     /*
-     * Base command line (use nmake environment)
+     * Base command line.
      */
 
-    n = GetEnvironmentVariable("CC", cmdline, 255);
-    cmdline[n] = 0;
-    if (n == 0)
-	lstrcpy(cmdline, "cl.exe");
-
-    strncat(cmdline, " -nologo -c -TC -Zs -X ", 255);
+    lstrcpy(cmdline, "cl.exe -nologo -c -TC -Zs -X -Fp.\\_junk.pch ");
 
     /*
      * Append our option for testing
@@ -218,7 +235,7 @@
 
     if (!ok) {
 	DWORD err = GetLastError();
-	int chars = wnsprintf(msg, sizeof(msg) - 1,
+	int chars = snprintf(msg, sizeof(msg) - 1,
 		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
 
 	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
@@ -256,23 +273,10 @@
      * Wait for our pipe to get done reading, should it be a little slow.
      */
 
-    WaitForMultipleObjects(2, pipeThreads, TRUE, INFINITE);
+    WaitForMultipleObjects(2, pipeThreads, TRUE, 500);
     CloseHandle(pipeThreads[0]);
     CloseHandle(pipeThreads[1]);
 
-#ifdef _DEBUG
-    {
-	DWORD err = 0;
-	lstrcat(cmdline, "\n");
-	WriteFile(GetStdHandle(STD_ERROR_HANDLE), cmdline, 
-	    lstrlen(cmdline), &err, NULL);
-	WriteFile(GetStdHandle(STD_ERROR_HANDLE), Out.buffer, 
-	    lstrlen(Out.buffer), &err,NULL);
-	WriteFile(GetStdHandle(STD_ERROR_HANDLE), Err.buffer,
-	    lstrlen(Err.buffer), &err,NULL);
-    }
-#endif
-
     /*
      * Look for the commandline warning code in both streams.
      *  - in MSVC 6 & 7 we get D4002, in MSVC 8 we get D9002.
@@ -357,7 +361,7 @@
 
     if (!ok) {
 	DWORD err = GetLastError();
-	int chars = wnsprintf(msg, sizeof(msg) - 1,
+	int chars = snprintf(msg, sizeof(msg) - 1,
 		"Tried to launch: \"%s\", but got error [%u]: ", cmdline, err);
 
 	FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM|FORMAT_MESSAGE_IGNORE_INSERTS|
@@ -403,13 +407,12 @@
      * Look for the commandline warning code in the stderr stream.
      */
 
-    return !(IsIn(Out.buffer, "LNK1117") ||
-	     IsIn(Err.buffer, "LNK1117") ||
-	     IsIn(Out.buffer, "LNK4044") ||
-	     IsIn(Err.buffer, "LNK4044"));
+    return !(strstr(Out.buffer, "LNK1117") != NULL ||
+             strstr(Err.buffer, "LNK1117") != NULL ||
+             strstr(Out.buffer, "LNK4044") != NULL ||
+             strstr(Err.buffer, "LNK4044") != NULL);
 }
 
-#if 1
 DWORD WINAPI
 ReadFromPipe(
     LPVOID args)
@@ -434,75 +437,103 @@
 
     return 0;  /* makes the compiler happy */
 }
-#else
-DWORD WINAPI
-ReadFromPipe (LPVOID args)
+
+int
+IsIn(
+    const char *string,
+    const char *substring)
 {
-    pipeinfo *pi = (pipeinfo *) args;
-    char *lastBuf = pi->buffer;
-    DWORD dwRead;
-    BOOL ok;
-
-again:
-    ok = ReadFile(pi->pipe, lastBuf, 25, &dwRead, 0L);
-    if (!ok || dwRead == 0) {
-        CloseHandle(pi->pipe);
-        return 0;
-    }
-    lastBuf += dwRead;
-    goto again;
-
-    return 0;  /* makes the compiler happy */
+    return (strstr(string, substring) != NULL);
 }
-#endif
 
+/*
+ * Find a specified #define by name.
+ *
+ * If the line is '#define TCL_VERSION "8.5"', it returns 85 as the result.
+ */
+
 int
-IsIn (const char *string, const char *substring)
+GrepForDefine(
+    const char *file,
+    const char *string)
 {
-    return (strstr(string, substring) != NULL);
+    FILE *f;
+    char s1[51], s2[51], s3[51];
+    int r = 0;
+    double d1;
+
+    f = fopen(file, "rt");
+    if (f == NULL) {
+	return 0;
+    }
+
+    do {
+	r = fscanf(f, "%50s", s1);
+	if (r == 1 && !strcmp(s1, "#define")) {
+	    /*
+	     * Get next two words.
+	     */
+
+	    r = fscanf(f, "%50s %50s", s2, s3);
+	    if (r != 2) {
+		continue;
+	    }
+
+	    /*
+	     * Is the first word what we're looking for?
+	     */
+
+	    if (!strcmp(s2, string)) {
+		fclose(f);
+
+		/*
+		 * Add 1 past first double quote char. "8.5"
+		 */
+
+		d1 = atof(s3 + 1);		  /*    8.5  */
+		while (floor(d1) != d1) {
+		    d1 *= 10.0;
+		}
+		return ((int) d1);		  /*    85   */
+	    }
+	}
+    } while (!feof(f));
+
+    fclose(f);
+    return 0;
 }
 
-static double
-ReadVersionFromHeader(const char *file, const char *macro)
+/*
+ * GetVersionFromFile --
+ * 	Looks for a match string in a file and then returns the version
+ * 	following the match where a version is anything acceptable to 
+ *	package provide or package ifneeded.
+ */
+
+const char *
+GetVersionFromFile(const char *filename, const char *match)
 {
-    double d = 0.0;
-    CHAR szBuffer[100];
-    LPSTR p;
-    DWORD cbBuffer = 100;
-    FILE *fp = fopen(file, "r");
+    size_t cbBuffer = 100;
+    static char szBuffer[100];
+    char *szResult = NULL;
+    FILE *fp = fopen(filename, "r");
     if (fp != NULL) {
+	/* read data until we see our match string */
 	while (fgets(szBuffer, cbBuffer, fp) != NULL) {
-	    if ((p = strstr(szBuffer, macro)) != NULL) {
+	    LPSTR p, q;
+	    if ((p = strstr(szBuffer, match)) != NULL) {
+		/* skip to first digit */
 		while (*p && !isdigit(*p)) ++p;
-		d = strtod(p, NULL);
+		/* find ending whitespace */
+		q = p;
+		while (*q && (isalnum(*q) || *q == '.')) ++q;
+		memcpy(szBuffer, p, (q - p));
+		szBuffer[(q-p)] = 0;
+		szResult = szBuffer;
 		break;
 	    }
 	}
 	fclose(fp);
     }
-    return d;
-}
-
-int
-GetVersionFromHeader(const char *tclh, const char *tkh)
-{
-    double dTcl = 0.0, dTk = 0.0;
-    
-    if (tclh != NULL)
-	dTcl = ReadVersionFromHeader(tclh, "TCL_VERSION");
-    if (tkh != NULL)
-	dTk = ReadVersionFromHeader(tkh, "TK_VERSION");
-
-    if (dTcl > 0 || dTk > 0) {
-	FILE *ofp = fopen("version.vc", "w");
-	if (dTcl > 0)
-	    fprintf(ofp, "TCL_DOTVERSION\t= %0.1f\nTCL_VERSION\t= %u\n",
-		    dTcl, (int)(dTcl * 10.0));
-	if (dTk > 0)
-	    fprintf(ofp, "TK_DOTVERSION\t= %0.1f\nTK_VERSION\t= %u\n",
-		    dTk, (int)(dTk * 10.0));
-	fclose(ofp);
-	return 0;
-    }
-    return 1;
+    return szResult;
 }
Index: win/rules.vc
===================================================================
RCS file: /cvsroot/tcl/sampleextension/win/rules.vc,v
retrieving revision 1.5
diff -u -r1.5 rules.vc
--- win/rules.vc	8 Oct 2006 16:28:28 -0000	1.5
+++ win/rules.vc	27 Mar 2007 14:17:59 -0000
@@ -295,7 +295,7 @@
 #   x = special static build when it
 #	links to the dynamic C run-time.
 #----------------------------------------
-SUFX	    = sgx
+SUFX	    = tsgx
 
 !if $(DEBUG)
 BUILDDIRTOP = Debug
