mingw fixes:

1) mingw needs an #include to have access to mkdir.

2) It needs to always #include port.h (this is an identical
bit of code, in configure.ac, that I have in other opensource
projects for mingw support.)

3) I moved some code from port.cc to port.h, so I didn't have
to add logic to link in port.cc for mingw.

Last change before new release!  (*knock on wood*)  Submitting
TBR so I can get the release out today.  This isn't exactly a
trivial change, so I'm chary to submit TBR, but it's pretty
isolated to windows and mingw, and I've tested on those
platforms to make sure they compile and all tests pass.

DELTA=70  (37 added, 30 deleted, 3 changed)


Revision created by MOE tool push_codebase.
MOE_MIGRATION=2823


git-svn-id: https://gflags.googlecode.com/svn/trunk@54 6586e3c6-dcc4-952a-343f-ff74eb82781d
diff --git a/configure b/configure
index 073c80f..d1d2575 100755
--- a/configure
+++ b/configure
Binary files differ
diff --git a/configure.ac b/configure.ac
index 8538b28..94686c5 100644
--- a/configure.ac
+++ b/configure.ac
@@ -23,6 +23,15 @@
 AM_CONDITIONAL(GCC, test "$GCC" = yes)   # let the Makefile know if we're gcc
 AC_CANONICAL_HOST
 
+# MinGW uses autoconf, but also needs the windows shim routines
+# (since it doesn't have its own support for, say, pthreads).
+# This requires us to #include a special header file, and also to
+# link in some windows versions of .o's instead of the unix versions.
+AH_BOTTOM([
+#if defined( __MINGW32__) || defined(__MINGW64__)
+#include "windows/port.h"
+#endif
+])
 # Populate $host_cpu, $host_os, etc.
 AC_CANONICAL_HOST
 case $host_os in
diff --git a/src/config.h.in b/src/config.h.in
index 28dfa37..5338b73 100644
--- a/src/config.h.in
+++ b/src/config.h.in
@@ -98,3 +98,9 @@
 
 /* Puts following code inside the Google namespace */
 #undef _START_GOOGLE_NAMESPACE_
+
+
+#if defined( __MINGW32__) || defined(__MINGW64__)
+#include "windows/port.h"
+#endif
+
diff --git a/src/util.h b/src/util.h
index 8170c0a..f1d0016 100644
--- a/src/util.h
+++ b/src/util.h
@@ -227,22 +227,28 @@
 
 // Tries to create the directory path as a temp-dir.  If it fails,
 // changes path to some directory it *can* create.
-inline void MakeTmpdir(std::string* path) {
 #if defined(__MINGW32__)
+#include <io.h>
+inline void MakeTmpdir(std::string* path) {
   // I had trouble creating a directory in /tmp from mingw
   *path = "./gflags_unittest_testdir";
   mkdir(path->c_str());   // mingw has a weird one-arg mkdir
+}
 #elif defined(_MSC_VER)
+#include <direct.h>
+inline void MakeTmpdir(std::string* path) {
   char tmppath_buffer[1024];
   int tmppath_len = GetTempPathA(sizeof(tmppath_buffer), tmppath_buffer);
   assert(tmppath_len > 0 && tmppath_len < sizeof(tmppath_buffer));
   assert(tmppath_buffer[tmppath_len - 1] == '\\');   // API guarantees it
   *path = std::string(tmppath_buffer) + "gflags_unittest_testdir";
   _mkdir(path->c_str());
-#else
-  mkdir(path->c_str(), 0755);
-#endif
 }
+#else
+inline void MakeTmpdir(std::string* path) {
+  mkdir(path->c_str(), 0755);
+}
+#endif
 
 // -- string routines --------------------------------------------------------
 
diff --git a/src/windows/port.cc b/src/windows/port.cc
index cbe1307..fb47698 100644
--- a/src/windows/port.cc
+++ b/src/windows/port.cc
@@ -37,7 +37,6 @@
 
 #include <config.h>
 #include <string.h>    // for strlen(), memset(), memcmp()
-#include <stdlib.h>    // for _putenv, etc.
 #include <assert.h>
 #include <stdarg.h>    // for va_list, va_start, va_end
 #include <windows.h>
@@ -61,25 +60,3 @@
   return r;
 }
 #endif  /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
-
-void setenv(const char* name, const char* value, int) {
-  // In windows, it's impossible to set a variable to the empty string.
-  // We handle this by setting it to "0" and the NUL-ing out the \0.
-  // That is, we putenv("FOO=0") and then find out where in memory the
-  // putenv wrote "FOO=0", and change it in-place to "FOO=\0".
-  // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508
-  static const char* const kFakeZero = "0";
-  if (*value == '\0')
-    value = kFakeZero;
-  // Apparently the semantics of putenv() is that the input
-  // must live forever, so we leak memory here. :-(
-  const int nameval_len = strlen(name) + 1 + strlen(value) + 1;
-  char* nameval = reinterpret_cast<char*>(malloc(nameval_len));
-  snprintf(nameval, nameval_len, "%s=%s", name, value);
-  _putenv(nameval);
-  if (value == kFakeZero) {
-    nameval[nameval_len - 2] = '\0';   // works when putenv() makes no copy
-    if (*getenv(name) != '\0')
-      *getenv(name) = '\0';            // works when putenv() copies nameval
-  }
-}
diff --git a/src/windows/port.h b/src/windows/port.h
index be8eb1f..eea4eb5 100644
--- a/src/windows/port.h
+++ b/src/windows/port.h
@@ -40,12 +40,6 @@
 #ifndef GOOGLE_GFLAGS_WINDOWS_PORT_H_
 #define GOOGLE_GFLAGS_WINDOWS_PORT_H_
 
-// You should never include this file directly, but always include it
-// from either config.h (MSVC) or mingw.h (MinGW/msys).
-#if !defined(GOOGLE_GFLAGS_WINDOWS_CONFIG_H_)
-# error "port.h should only be included from config.h"
-#endif
-
 #ifdef _WIN32
 
 #ifndef WIN32_LEAN_AND_MEAN
@@ -53,6 +47,7 @@
 #endif
 #include <windows.h>
 #include <direct.h>          /* for mkdir */
+#include <stdlib.h>          /* for _putenv, getenv */
 #include <stdio.h>           /* need this to override stdio's snprintf */
 #include <stdarg.h>          /* util.h uses va_copy */
 #include <string.h>          /* for _stricmp */
@@ -70,7 +65,27 @@
 #define va_copy(dst, src)  (dst) = (src)
 #endif  /* #if !defined(__MINGW32__) && !defined(__MINGW64__) */
 
-extern void GFLAGS_DLL_DECL setenv(const char* name, const char* value, int);
+inline void setenv(const char* name, const char* value, int) {
+  // In windows, it's impossible to set a variable to the empty string.
+  // We handle this by setting it to "0" and the NUL-ing out the \0.
+  // That is, we putenv("FOO=0") and then find out where in memory the
+  // putenv wrote "FOO=0", and change it in-place to "FOO=\0".
+  // c.f. http://svn.apache.org/viewvc/stdcxx/trunk/tests/src/environ.cpp?r1=611451&r2=637508&pathrev=637508
+  static const char* const kFakeZero = "0";
+  if (*value == '\0')
+    value = kFakeZero;
+  // Apparently the semantics of putenv() is that the input
+  // must live forever, so we leak memory here. :-(
+  const int nameval_len = strlen(name) + 1 + strlen(value) + 1;
+  char* nameval = reinterpret_cast<char*>(malloc(nameval_len));
+  snprintf(nameval, nameval_len, "%s=%s", name, value);
+  _putenv(nameval);
+  if (value == kFakeZero) {
+    nameval[nameval_len - 2] = '\0';   // works when putenv() makes no copy
+    if (*getenv(name) != '\0')
+      *getenv(name) = '\0';            // works when putenv() copies nameval
+  }
+}
 
 #define strcasecmp   _stricmp