re2c: Work around tmpfile() issue on win32.

tmpfile() defaults to C:\, and on Windows 7 can run into permissions issues.
Add workaround implementation from cairo
(http://cgit.freedesktop.org/cairo/commit/?id=4fa46e3caaffb54f4419887418d8d0ea39816092)

See also: http://msdn.microsoft.com/en-us/library/x8x7sakw(v=VS.80).aspx
(community content section)
diff --git a/tools/re2c/code.c b/tools/re2c/code.c
index 8a78eaa..bd54baa 100644
--- a/tools/re2c/code.c
+++ b/tools/re2c/code.c
@@ -1,3 +1,7 @@
+#ifdef _WIN32
+#include <windows.h>
+#include <io.h>
+#endif
 #include <stdlib.h>
 #include <string.h>
 #include <ctype.h>
@@ -6,6 +10,57 @@
 #include "tools/re2c/dfa.h"
 #include "tools/re2c/parse.h"
 
+#ifdef _WIN32
+/* tmpfile() replacment for Windows.
+ *
+ * On Windows tmpfile() creates the file in the root directory. This
+ * may fail due to unsufficient privileges.
+ */
+static FILE *
+win32_tmpfile (void)
+{
+    DWORD path_len;
+    WCHAR path_name[MAX_PATH + 1];
+    WCHAR file_name[MAX_PATH + 1];
+    HANDLE handle;
+    int fd;
+    FILE *fp;
+
+    path_len = GetTempPathW (MAX_PATH, path_name);
+    if (path_len <= 0 || path_len >= MAX_PATH)
+	return NULL;
+
+    if (GetTempFileNameW (path_name, L"ps_", 0, file_name) == 0)
+	return NULL;
+
+    handle = CreateFileW (file_name,
+			 GENERIC_READ | GENERIC_WRITE,
+			 0,
+			 NULL,
+			 CREATE_ALWAYS,
+			 FILE_ATTRIBUTE_NORMAL | FILE_FLAG_DELETE_ON_CLOSE,
+			 NULL);
+    if (handle == INVALID_HANDLE_VALUE) {
+	DeleteFileW (file_name);
+	return NULL;
+    }
+
+    fd = _open_osfhandle((intptr_t) handle, 0);
+    if (fd < 0) {
+	CloseHandle (handle);
+	return NULL;
+    }
+
+    fp = fdopen(fd, "w+b");
+    if (fp == NULL) {
+	_close(fd);
+	return NULL;
+    }
+
+    return fp;
+}
+#endif
+
 static void useLabel(size_t value) {
     while (value >= vUsedLabelAlloc) {
 	vUsedLabels = realloc(vUsedLabels, vUsedLabelAlloc * 2);
@@ -844,7 +899,11 @@
     nOrgOline = oline;
     maxFillIndexes = vFillIndexes;
     orgVFillIndexes = vFillIndexes;
+#ifdef _WIN32
+    tmpo = win32_tmpfile();
+#else
     tmpo = tmpfile();
+#endif
     for(s = d->head; s; s = s->next){
 	int readCh = 0;
 	State_emit(s, tmpo, &readCh);