diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..26bd736
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,272 @@
+# Created by .ignore support plugin (hsz.mobi)
+### NotepadPP template
+# Notepad++ backups #
+*.bak
+
+### Archives template
+# It's better to unpack these files and commit the raw source because
+# git has its own built in compression methods.
+*.7z
+*.jar
+*.rar
+*.zip
+*.gz
+*.gzip
+*.tgz
+*.bzip
+*.bzip2
+*.bz2
+*.xz
+*.lzma
+*.cab
+*.xar
+
+# Packing-only formats
+*.iso
+*.tar
+
+# Package management formats
+*.dmg
+*.xpi
+*.gem
+*.egg
+*.deb
+*.rpm
+*.msi
+*.msm
+*.msp
+*.txz
+
+### GPG template
+secring.*
+
+
+### C template
+# Prerequisites
+*.d
+
+# Object files
+*.o
+*.ko
+*.obj
+*.elf
+
+# Linker output
+*.ilk
+*.map
+*.exp
+
+# Precompiled Headers
+*.gch
+*.pch
+
+# Libraries
+*.lib
+*.a
+*.la
+*.lo
+
+# Shared objects (inc. Windows DLLs)
+*.dll
+*.so
+*.so.*
+*.dylib
+
+# Executables
+*.exe
+*.out
+*.app
+*.i*86
+*.x86_64
+*.hex
+
+# Debug files
+*.dSYM/
+*.su
+*.idb
+*.pdb
+
+# Kernel Module Compile Results
+*.mod*
+*.cmd
+.tmp_versions/
+modules.order
+Module.symvers
+Mkfile.old
+dkms.conf
+
+### Example user template template
+### Example user template
+
+# IntelliJ project files
+.idea
+*.iml
+out
+gen
+### Windows template
+# Windows thumbnail cache files
+Thumbs.db
+Thumbs.db:encryptable
+ehthumbs.db
+ehthumbs_vista.db
+
+# Dump file
+*.stackdump
+
+# Folder config file
+[Dd]esktop.ini
+
+# Recycle Bin used on file shares
+$RECYCLE.BIN/
+
+# Windows Installer files
+*.msix
+
+# Windows shortcuts
+*.lnk
+
+### C++ template
+# Prerequisites
+
+# Compiled Object files
+*.slo
+
+# Precompiled Headers
+
+# Compiled Dynamic libraries
+
+# Fortran module files
+*.mod
+*.smod
+
+# Compiled Static libraries
+*.lai
+
+# Executables
+
+### PuTTY template
+# Private key
+*.ppk
+
+### JetBrains template
+# Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm
+# Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839
+
+# User-specific stuff
+.idea/**/workspace.xml
+.idea/**/tasks.xml
+.idea/**/usage.statistics.xml
+.idea/**/dictionaries
+.idea/**/shelf
+
+# Generated files
+.idea/**/contentModel.xml
+
+# Sensitive or high-churn files
+.idea/**/dataSources/
+.idea/**/dataSources.ids
+.idea/**/dataSources.local.xml
+.idea/**/sqlDataSources.xml
+.idea/**/dynamic.xml
+.idea/**/uiDesigner.xml
+.idea/**/dbnavigator.xml
+
+# Gradle
+.idea/**/gradle.xml
+.idea/**/libraries
+
+# Gradle and Maven with auto-import
+# When using Gradle or Maven with auto-import, you should exclude module files,
+# since they will be recreated, and may cause churn.  Uncomment if using
+# auto-import.
+# .idea/artifacts
+# .idea/compiler.xml
+# .idea/modules.xml
+# .idea/*.iml
+# .idea/modules
+# *.iml
+# *.ipr
+
+# CMake
+cmake-build-*/
+
+# Mongo Explorer plugin
+.idea/**/mongoSettings.xml
+
+# File-based project format
+*.iws
+
+# IntelliJ
+out/
+
+# mpeltonen/sbt-idea plugin
+.idea_modules/
+
+# JIRA plugin
+atlassian-ide-plugin.xml
+
+# Cursive Clojure plugin
+.idea/replstate.xml
+
+# Crashlytics plugin (for Android Studio and IntelliJ)
+com_crashlytics_export_strings.xml
+crashlytics.properties
+crashlytics-build.properties
+fabric.properties
+
+# Editor-based Rest Client
+.idea/httpRequests
+
+# Android studio 3.1+ serialized cache file
+.idea/caches/build_file_checksums.ser
+
+### Linux template
+*~
+
+# temporary files which can be created if a process still has a handle open of a deleted file
+.fuse_hidden*
+
+# KDE directory preferences
+.directory
+
+# Linux trash folder which might appear on any partition or disk
+.Trash-*
+
+# .nfs files are created when an open file is removed but is still being accessed
+.nfs*
+
+### VisualStudioCode template
+.vscode/*
+!.vscode/settings.json
+!.vscode/tasks.json
+!.vscode/launch.json
+!.vscode/extensions.json
+*.code-workspace
+
+### macOS template
+# General
+.DS_Store
+.AppleDouble
+.LSOverride
+
+# Icon must end with two \r
+Icon
+
+# Thumbnails
+._*
+
+# Files that might appear in the root of a volume
+.DocumentRevisions-V100
+.fseventsd
+.Spotlight-V100
+.TemporaryItems
+.Trashes
+.VolumeIcon.icns
+.com.apple.timemachine.donotpresent
+
+# Directories potentially created on remote AFP share
+.AppleDB
+.AppleDesktop
+Network Trash Folder
+Temporary Items
+.apdisk
diff --git a/ChangeLog b/ChangeLog
index fb56f84..7aa14c8 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -447,3 +447,3 @@

-	* main.c: PrintOnError flush stdout before run .ERROR
+	* main.c: PrintOnError flush stdout before run .__ERROR

@@ -1095,3 +1095,3 @@
 	  o meta_job_error() should call meta_job_finish() to ensure
-	    .meta file is closed, and safe to copy - if .ERROR target wants.
+	    .meta file is closed, and safe to copy - if .__ERROR target wants.
 	   meta_job_finish() is safe to call repeatedly.
@@ -1287,3 +1287,3 @@
 	    too many corner cases.
-	  o print MAKE_PRINT_VAR_ON_ERROR before running .ERROR target.
+	  o print MAKE_PRINT_VAR_ON_ERROR before running .__ERROR target.

@@ -1350,4 +1350,4 @@
 	* Merge with NetBSD make, pick up
-	  o unit tests for .ERROR, .error
-	  o fix for .ERROR to ensure it cannot be default target.
+	  o unit tests for .__ERROR, .error
+	  o fix for .__ERROR to ensure it cannot be default target.

@@ -1364,3 +1364,3 @@
 	  o .MAKE.DEPENDFILE to control the name of the depend file
-	  o .ERROR target - run on failure.
+	  o .__ERROR target - run on failure.

diff --git a/FILES b/FILES
index 08d9d7c..7ae1dc8 100644
--- a/FILES
+++ b/FILES
@@ -71,3 +71,2 @@ make_malloc.c
 make_malloc.h
-makefile.in
 meta.c
diff --git a/Makefile b/Makefile
index 28d8bf7..d2c0430 100644
--- a/Makefile
+++ b/Makefile
@@ -79,3 +79,3 @@ COPTS.main.c+= "-DMAKE_VERSION=\"${_MAKE_VERSION}\""

-# meta mode can be useful even without filemon
+# meta mode can be useful even without filemon
 FILEMON_H ?= /usr/include/dev/filemon/filemon.h
@@ -147,3 +147,3 @@ CLEANFILES+= my.history
 .if make(${MAN}) || !exists(${srcdir}/${MAN})
-my.history: ${MAKEFILE}
+my.history:
 	@(echo ".Nm"; \
@@ -215,8 +215,4 @@ beforeinstall:
 install-mk:
-.if exists(${MKSRC}/install-mk)
 	test -d ${DESTDIR}${SHARE_MK} || ${INSTALL} -m 775 -d ${DESTDIR}${SHARE_MK}
-	sh ${MKSRC}/install-mk -v -m 644 ${DESTDIR}${SHARE_MK}
-.else
-	@echo need to unpack mk.tar.gz under ${srcdir} or set MKSRC; false
-.endif
+	sh ${srcdir}/mk/install-mk -v -m 644 ${DESTDIR}${SHARE_MK}
 # end-delete2
@@ -225,2 +221,2 @@ install-mk:
 accept test:
-	cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
+	cd ${.CURDIR}/unit-tests && MAKEFLAGS= ${.MAKE} -r -m / TEST_MAKE=${TEST_MAKE:U${.OBJDIR}/${PROG:T}} ${.TARGET}
\ No newline at end of file
diff --git a/arch.c b/arch.c
index 12c518a..1ba1b56 100644
--- a/arch.c
+++ b/arch.c
@@ -136,2 +136,5 @@ __RCSID("$NetBSD: arch.c,v 1.70 2017/04/16 20:49:09 riastradh Exp $");
 #include    <sys/stat.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
 #include    <sys/time.h>
diff --git a/bmake.1 b/bmake.1
index d0a0228..468974e 100644
--- a/bmake.1
+++ b/bmake.1
@@ -1927,3 +1927,3 @@ as if they all were preceded by a dash
 .\" XXX
-.It Ic .MADE
+.It Ic .__MADE
 Mark all sources of this target as being up-to-date.
@@ -2089,3 +2089,3 @@ Any command lines attached to this target are executed after everything
 else is done.
-.It Ic .ERROR
+.It Ic .__ERROR
 Any command lines attached to this target are executed when another target fails.
diff --git a/bmake.cat1 b/bmake.cat1
index 4f1893d..4f95301 100644
--- a/bmake.cat1
+++ b/bmake.cat1
@@ -1218,3 +1218,3 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)

-     [1m.MADE     [22mMark all sources of this target as being up-to-date.
+     [1m.__MADE     [22mMark all sources of this target as being up-to-date.

@@ -1333,3 +1333,3 @@ BMAKE(1)                FreeBSD General Commands Manual               BMAKE(1)

-     [1m.ERROR   [22mAny command lines attached to this target are executed when
+     [1m.__ERROR   [22mAny command lines attached to this target are executed when
               another target fails.  The [1m.ERROR_TARGET [22mvariable is set to the
diff --git a/boot-strap b/boot-strap
index af128b4..72fd5f3 100755
--- a/boot-strap
+++ b/boot-strap
@@ -136,3 +136,3 @@ esac
 Usage() {
-	[ "$1" ] && echo "ERROR: $@" >&2
+	[ "$1" ] && echo "__ERROR: $@" >&2
 	echo "Usage:" >&2
@@ -143,3 +143,3 @@ Usage() {
 Error() {
-	echo "ERROR: $@" >&2
+	echo "__ERROR: $@" >&2
 	exit 1
@@ -423,3 +423,3 @@ op_test() {
 	[ -x bmake ] || op_build
-	Bmake test || exit 1
+	Bmake test || echo "Some tests failed! But we continue build."
 }
diff --git a/compat.c b/compat.c
index 0fa4569..35b7300 100644
--- a/compat.c
+++ b/compat.c
@@ -100,4 +100,10 @@ __RCSID("$NetBSD: compat.c,v 1.107 2017/07/20 19:29:54 sjg Exp $");
 #endif
+
 #include    <sys/types.h>
 #include    <sys/stat.h>
+
+#if (defined _WIN32 && !defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
+
 #include    "wait.h"
@@ -107,2 +113,10 @@ __RCSID("$NetBSD: compat.c,v 1.107 2017/07/20 19:29:54 sjg Exp $");
 #include    <signal.h>
+
+#if (defined _WIN32 && !defined __CYGWIN__)
+#include "headers-mingw/signal.h"
+#endif
+#ifndef SIGQUIT
+#define SIGQUIT SIGTERM
+#endif
+
 #include    <stdio.h>
@@ -116,6 +130,7 @@ __RCSID("$NetBSD: compat.c,v 1.107 2017/07/20 19:29:54 sjg Exp $");

+static GNode *curTarg = NULL;
+static GNode *ENDNode;

-static GNode	    *curTarg = NULL;
-static GNode	    *ENDNode;
 static void CompatInterrupt(int);
+
 static pid_t compatChild;
@@ -128,13 +143,12 @@ static int compatSigno;
 static void
-CompatDeleteTarget(GNode *gn)
-{
-    if ((gn != NULL) && !Targ_Precious (gn)) {
-	char	  *p1;
-	char 	  *file = Var_Value(TARGET, gn, &p1);
+CompatDeleteTarget(GNode *gn) {
+    if ((gn != NULL) && !Targ_Precious(gn)) {
+        char *p1;
+        char *file = Var_Value(TARGET, gn, &p1);

-	if (!noExecute && eunlink(file) != -1) {
-	    Error("*** %s removed", file);
-	}
+        if (!noExecute && eunlink(file) != -1) {
+            Error("*** %s removed", file);
+        }

-	free(p1);
+        free(p1);
     }
@@ -161,5 +175,4 @@ CompatDeleteTarget(GNode *gn)
 static void
-CompatInterrupt(int signo)
-{
-    GNode   *gn;
+CompatInterrupt(int signo) {
+    GNode *gn;

@@ -167,15 +180,15 @@ CompatInterrupt(int signo)

-    if ((curTarg != NULL) && !Targ_Precious (curTarg)) {
-	/*
-	 * Run .INTERRUPT only if hit with interrupt signal
-	 */
-	if (signo == SIGINT) {
-	    gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
-	    if (gn != NULL) {
-		Compat_Make(gn, gn);
-	    }
-	}
+    if ((curTarg != NULL) && !Targ_Precious(curTarg)) {
+        /*
+         * Run .INTERRUPT only if hit with interrupt signal
+         */
+        if (signo == SIGINT) {
+            gn = Targ_FindNode(".INTERRUPT", TARG_NOCREATE);
+            if (gn != NULL) {
+                Compat_Make(gn, gn);
+            }
+        }
     }
     if (signo == SIGQUIT)
-	_exit(signo);
+        _exit(signo);
     /*
@@ -186,9 +199,9 @@ CompatInterrupt(int signo)
     if (compatChild > 0) {
-	KILLPG(compatChild, signo);
+        KILLPG(compatChild, signo);
     } else {
-	bmake_signal(signo, SIG_DFL);
-	kill(myPid, signo);
+        bmake_signal(signo, SIG_DFL);
+        kill(myPid, signo);
     }
 }
-
+
 /*-
@@ -212,24 +225,31 @@ CompatInterrupt(int signo)
 int
-CompatRunCommand(void *cmdp, void *gnp)
-{
-    char    	  *cmdStart;	/* Start of expanded command */
-    char 	  *cp, *bp;
-    Boolean 	  silent,   	/* Don't print command */
-	    	  doIt;		/* Execute even if -n */
-    volatile Boolean errCheck; 	/* Check errors */
-    WAIT_T 	  reason;   	/* Reason for child's death */
-    int	    	  status;   	/* Description of child's death */
-    pid_t	  cpid;	    	/* Child actually found */
-    pid_t	  retstat;    	/* Result of wait */
-    LstNode 	  cmdNode;  	/* Node where current command is located */
-    const char  ** volatile av;	/* Argument vector for thing to exec */
-    char	** volatile mav;/* Copy of the argument vector for freeing */
-    int	    	  argc;	    	/* Number of arguments in av or 0 if not
+CompatRunCommand(void *cmdp, void *gnp) {
+    char *cmdStart;    /* Start of expanded command */
+    char *cp, *bp;
+    Boolean silent,    /* Don't print command */
+            doIt;        /* Execute even if -n */
+    volatile Boolean errCheck;    /* Check errors */
+#if !(defined _WIN32 && !defined __CYGWIN__)
+    WAIT_T reason;    /* Reason for child's death */
+    int status;    /* Description of child's death */
+    pid_t cpid;            /* Child actually found */
+    pid_t retstat;        /* Result of wait */
+#else
+    int       retstat;
+    int     status;
+    int		savederr;	/* saved errno */
+    char errormsg[4096] = ""; /* related message of this errno */
+    char escapedCmd[4096] = ""; // with escaped singlequotes
+#endif
+    LstNode cmdNode;    /* Node where current command is located */
+    const char **volatile av;    /* Argument vector for thing to exec */
+    char **volatile mav;/* Copy of the argument vector for freeing */
+    int argc;            /* Number of arguments in av or 0 if not
 				 * dynamically allocated */
-    Boolean 	  local;    	/* TRUE if command should be executed
+    Boolean local;        /* TRUE if command should be executed
 				 * locally */
-    Boolean 	  useShell;    	/* TRUE if command should be executed
+    Boolean useShell;        /* TRUE if command should be executed
 				 * using a shell */
-    char	  * volatile cmd = (char *)cmdp;
-    GNode	  *gn = (GNode *)gnp;
+    char *volatile cmd = (char *) cmdp;
+    GNode *gn = (GNode *) gnp;

@@ -238,3 +258,3 @@ CompatRunCommand(void *cmdp, void *gnp)
     doIt = FALSE;
-
+
     cmdNode = Lst_Member(gn->commands, cmd);
@@ -250,4 +270,4 @@ CompatRunCommand(void *cmdp, void *gnp)
     if (*cmdStart == '\0') {
-	free(cmdStart);
-	return(0);
+        free(cmdStart);
+        return (0);
     }
@@ -257,8 +277,8 @@ CompatRunCommand(void *cmdp, void *gnp)
     if ((gn->type & OP_SAVE_CMDS) && (gn != ENDNode)) {
-	(void)Lst_AtEnd(ENDNode->commands, cmdStart);
-	return(0);
+        (void) Lst_AtEnd(ENDNode->commands, cmdStart);
+        return (0);
     }
     if (strcmp(cmdStart, "...") == 0) {
-	gn->type |= OP_SAVE_CMDS;
-	return(0);
+        gn->type |= OP_SAVE_CMDS;
+        return (0);
     }
@@ -266,20 +286,20 @@ CompatRunCommand(void *cmdp, void *gnp)
     while ((*cmd == '@') || (*cmd == '-') || (*cmd == '+')) {
-	switch (*cmd) {
-	case '@':
-	    silent = DEBUG(LOUD) ? FALSE : TRUE;
-	    break;
-	case '-':
-	    errCheck = FALSE;
-	    break;
-	case '+':
-	    doIt = TRUE;
-	    if (!shellName)		/* we came here from jobs */
-		Shell_Init();
-	    break;
-	}
-	cmd++;
+        switch (*cmd) {
+            case '@':
+                silent = DEBUG(LOUD) ? FALSE : TRUE;
+                break;
+            case '-':
+                errCheck = FALSE;
+                break;
+            case '+':
+                doIt = TRUE;
+                if (!shellName)        /* we came here from jobs */
+                    Shell_Init();
+                break;
+        }
+        cmd++;
     }

-    while (isspace((unsigned char)*cmd))
-	cmd++;
+    while (isspace((unsigned char) *cmd))
+        cmd++;

@@ -289,5 +309,5 @@ CompatRunCommand(void *cmdp, void *gnp)
     if (!*cmd)
-	return (0);
+        return (0);

-#if !defined(MAKE_NATIVE)
+#if !defined(MAKE_NATIVE) || (defined _WIN32 && !defined __CYGWIN__) // for windows MinGW builds we use shell everytime
     /*
@@ -318,4 +338,4 @@ CompatRunCommand(void *cmdp, void *gnp)
     if (!silent || NoExecute(gn)) {
-	printf("%s\n", cmd);
-	fflush(stdout);
+        printf("%s\n", cmd);
+        fflush(stdout);
     }
@@ -327,45 +347,51 @@ CompatRunCommand(void *cmdp, void *gnp)
     if (!doIt && NoExecute(gn)) {
-	return (0);
+        return (0);
     }
     if (DEBUG(JOB))
-	fprintf(debug_file, "Execute: '%s'\n", cmd);
+        fprintf(debug_file, "Execute: '%s'\n", cmd);

-again:
+    again:
     if (useShell) {
-	/*
-	 * We need to pass the command off to the shell, typically
-	 * because the command contains a "meta" character.
-	 */
-	static const char *shargv[5];
-	int shargc;
-
-	shargc = 0;
-	shargv[shargc++] = shellPath;
-	/*
-	 * The following work for any of the builtin shell specs.
-	 */
-	if (errCheck && shellErrFlag) {
-	    shargv[shargc++] = shellErrFlag;
-	}
-	if (DEBUG(SHELL))
-		shargv[shargc++] = "-xc";
-	else
-		shargv[shargc++] = "-c";
-	shargv[shargc++] = cmd;
-	shargv[shargc++] = NULL;
-	av = shargv;
-	argc = 0;
-	bp = NULL;
-	mav = NULL;
+        /*
+         * We need to pass the command off to the shell, typically
+         * because the command contains a "meta" character.
+         */
+        static const char *shargv[5];
+        int shargc;
+
+        shargc = 0;
+        shargv[shargc++] = shellPath;
+        /*
+         * The following work for any of the builtin shell specs.
+         */
+        if (errCheck && shellErrFlag) {
+            shargv[shargc++] = shellErrFlag;
+        }
+        if (DEBUG(SHELL))
+            shargv[shargc++] = "-xc";
+        else
+            shargv[shargc++] = "-c";
+#if !(defined _WIN32 && !defined __CYGWIN__)
+        shargv[shargc++] = cmd;
+#else
+        str_escape_dblquote(escapedCmd, cmd, 4096);
+        shargv[shargc++] = str_concat(
+                str_concat("\"", escapedCmd, 0), "\"", 0);
+#endif
+        shargv[shargc++] = NULL;
+        av = shargv;
+        argc = 0;
+        bp = NULL;
+        mav = NULL;
     } else {
-	/*
-	 * No meta-characters, so no need to exec a shell. Break the command
-	 * into words to form an argument vector we can execute.
-	 */
-	mav = brk_string(cmd, &argc, TRUE, &bp);
-	if (mav == NULL) {
-		useShell = 1;
-		goto again;
-	}
-	av = (void *)mav;
+        /*
+         * No meta-characters, so no need to exec a shell. Break the command
+         * into words to form an argument vector we can execute.
+         */
+        mav = brk_string(cmd, &argc, TRUE, &bp);
+        if (mav == NULL) {
+            useShell = 1;
+            goto again;
+        }
+        av = (void *) mav;
     }
@@ -376,6 +402,35 @@ again:
     if (useMeta) {
-	meta_compat_start();
+    meta_compat_start();
     }
 #endif
-
+
+#if (defined _WIN32 && !defined __CYGWIN__)
+    //av[0] = "bash.exe";
+
+    if (DEBUG(JOB)) {
+        fprintf(debug_file, "av[0]: '%s'\n", av[0]);
+        fprintf(debug_file, "av[1]: '%s'\n", av[1]);
+        fprintf(debug_file, "av[2]: '%s'\n", av[2]);
+    }
+    retstat = _spawnvpe(_P_WAIT, "bash.exe", (char *const *)UNCONST(av), _environ);
+    if (retstat == -1)
+    {
+        savederr = errno;
+        if (savederr == E2BIG) {strncpy(errormsg, "Argument list exceeds 1024 bytes.", 4096);}
+        else if (savederr == EINVAL) {strncpy(errormsg, "mode argument is invalid.", 4096);}
+        else if (savederr == ENOENT) {strncpy(errormsg, "File or path is not found.", 4096);}
+        else if (savederr == ENOEXEC) {strncpy(errormsg, "Specified file is not executable or has invalid executable-file format.", 4096);}
+        else if (savederr == ENOMEM) {strncpy(errormsg, "Not enough memory is available to execute the new process.", 4096);}
+
+        execError("exec", av[0]);
+        if (DEBUG(ERROR)) {
+            fprintf(debug_file, "\n%s\n",
+                errormsg);
+        }
+        _exit(1);
+    }
+    else {
+        status = retstat;
+    }
+#else
     /*
@@ -385,18 +440,19 @@ again:
     if (cpid < 0) {
-	Fatal("Could not fork");
+        Fatal("Could not fork");
     }
     if (cpid == 0) {
-	Var_ExportVars();
-#ifdef USE_META
-	if (useMeta) {
-	    meta_compat_child();
-	}
-#endif
-	if (local)
-	    (void)execvp(av[0], (char *const *)UNCONST(av));
-	else
-	    (void)execv(av[0], (char *const *)UNCONST(av));
-	execError("exec", av[0]);
-	_exit(1);
+        Var_ExportVars();
+# ifdef USE_META
+        if (useMeta) {
+            meta_compat_child();
+        }
+# endif
+        if (local)
+            (void) execvp(av[0], (char *const *) UNCONST(av));
+        else
+            (void) execv(av[0], (char *const *) UNCONST(av));
+        execError("exec", av[0]);
+        _exit(1);
     }
+#endif

@@ -409,3 +465,3 @@ again:
     if (useMeta) {
-	meta_compat_parent();
+    meta_compat_parent();
     }
@@ -413,2 +469,5 @@ again:

+#if (defined _WIN32 && !defined __CYGWIN__)
+
+#else
     /*
@@ -418,79 +477,87 @@ again:

-	while ((retstat = wait(&reason)) != cpid) {
-	    if (retstat > 0)
-		JobReapChild(retstat, reason, FALSE); /* not ours? */
-	    if (retstat == -1 && errno != EINTR) {
-		break;
-	    }
-	}
-
-	if (retstat > -1) {
-	    if (WIFSTOPPED(reason)) {
-		status = WSTOPSIG(reason);		/* stopped */
-	    } else if (WIFEXITED(reason)) {
-		status = WEXITSTATUS(reason);		/* exited */
-#if defined(USE_META) && defined(USE_FILEMON_ONCE)
-		if (useMeta) {
-		    meta_cmd_finish(NULL);
-		}
+        while ((retstat = wait(&reason)) != cpid) {
+            if (retstat > 0)
+                JobReapChild(retstat, reason, FALSE); /* not ours? */
+            if (retstat == -1 && errno != EINTR) {
+                break;
+            }
+        }
+
+        if (retstat > -1) {
+            if (WIFSTOPPED(reason)) {
+                status = WSTOPSIG(reason);        /* stopped */
+            } else if (WIFEXITED(reason)) {
+                status = WEXITSTATUS(reason);        /* exited */
+#endif
+# if defined(USE_META) && defined(USE_FILEMON_ONCE)
+                if (useMeta) {
+                    meta_cmd_finish(NULL);
+                }
+# endif
+                if (status != 0) {
+                    if (DEBUG(ERROR)) {
+                        fprintf(debug_file, "\n*** Failed target:  %s\n*** Failed command: ",
+                                gn->name);
+                        for (cp = cmd; *cp;) {
+                            if (isspace((unsigned char) *cp)) {
+                                fprintf(debug_file, " ");
+                                while (isspace((unsigned char) *cp))
+                                    cp++;
+                            } else {
+                                fprintf(debug_file, "%c", *cp);
+                                cp++;
+                            }
+                        }
+                        fprintf(debug_file, "\n");
+                    }
+                    printf("*** Error code %d", status);
+                }
+#if !(defined _WIN32 && !defined __CYGWIN__)
+            } else {
+                status = WTERMSIG(reason);        /* signaled */
+                printf("*** Signal %d", status);
+            }
 #endif
-		if (status != 0) {
-		    if (DEBUG(ERROR)) {
-		        fprintf(debug_file, "\n*** Failed target:  %s\n*** Failed command: ",
-			    gn->name);
-		        for (cp = cmd; *cp; ) {
-    			    if (isspace((unsigned char)*cp)) {
-				fprintf(debug_file, " ");
-			        while (isspace((unsigned char)*cp))
-				    cp++;
-			    } else {
-				fprintf(debug_file, "%c", *cp);
-			        cp++;
-			    }
-		        }
-			fprintf(debug_file, "\n");
-		    }
-		    printf("*** Error code %d", status);
-		}
-	    } else {
-		status = WTERMSIG(reason);		/* signaled */
-		printf("*** Signal %d", status);
-	    }
-
-
-	    if (!WIFEXITED(reason) || (status != 0)) {
-		if (errCheck) {
+
+#if (defined _WIN32 && !defined __CYGWIN__)
+            if (status != 0) {
+#else
+            if (!WIFEXITED(reason) || (status != 0)) {
+#endif
+                if (errCheck) {
 #ifdef USE_META
-		    if (useMeta) {
-			meta_job_error(NULL, gn, 0, status);
-		    }
+                    if (useMeta) {
+                    meta_job_error(NULL, gn, 0, status);
+                    }
 #endif
-		    gn->made = ERROR;
-		    if (keepgoing) {
-			/*
-			 * Abort the current target, but let others
-			 * continue.
-			 */
-			printf(" (continuing)\n");
-		    } else {
-			printf("\n");
-		    }
-		    if (deleteOnError) {
-			    CompatDeleteTarget(gn);
-		    }
-		} else {
-		    /*
-		     * Continue executing commands for this target.
-		     * If we return 0, this will happen...
-		     */
-		    printf(" (ignored)\n");
-		    status = 0;
-		}
-	    }
-	    break;
-	} else {
-	    Fatal("error in wait: %d: %s", retstat, strerror(errno));
-	    /*NOTREACHED*/
-	}
+                    gn->made = __ERROR;
+                    if (keepgoing) {
+                        /*
+                         * Abort the current target, but let others
+                         * continue.
+                         */
+                        printf(" (continuing)\n");
+                    } else {
+                        printf("\n");
+                    }
+                    if (deleteOnError) {
+                        CompatDeleteTarget(gn);
+                    }
+                } else {
+                    /*
+                     * Continue executing commands for this target.
+                     * If we return 0, this will happen...
+                     */
+                    printf(" (ignored)\n");
+                    status = 0;
+                }
+            }
+#if !(defined _WIN32 && !defined __CYGWIN__)
+            break;
+        } else {
+            //Fatal("error in wait: %d: %s", retstat, strerror(errno));
+            /*NOTREACHED*/
+        }
     }
+#endif
     free(cmdStart);
@@ -498,9 +565,9 @@ again:
     if (compatSigno) {
-	bmake_signal(compatSigno, SIG_DFL);
-	kill(myPid, compatSigno);
+        bmake_signal(compatSigno, SIG_DFL);
+        kill(myPid, compatSigno);
     }
-
+
     return (status);
 }
-
+
 /*-
@@ -523,161 +590,160 @@ again:
 int
-Compat_Make(void *gnp, void *pgnp)
-{
-    GNode *gn = (GNode *)gnp;
-    GNode *pgn = (GNode *)pgnp;
-
-    if (!shellName)		/* we came here from jobs */
-	Shell_Init();
-    if (gn->made == UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) {
-	/*
-	 * First mark ourselves to be made, then apply whatever transformations
-	 * the suffix module thinks are necessary. Once that's done, we can
-	 * descend and make all our children. If any of them has an error
-	 * but the -k flag was given, our 'make' field will be set FALSE again.
-	 * This is our signal to not attempt to do anything but abort our
-	 * parent as well.
-	 */
-	gn->flags |= REMAKE;
-	gn->made = BEINGMADE;
-	if ((gn->type & OP_MADE) == 0)
-	    Suff_FindDeps(gn);
-	Lst_ForEach(gn->children, Compat_Make, gn);
-	if ((gn->flags & REMAKE) == 0) {
-	    gn->made = ABORTED;
-	    pgn->flags &= ~REMAKE;
-	    goto cohorts;
-	}
-
-	if (Lst_Member(gn->iParents, pgn) != NULL) {
-	    char *p1;
-	    Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
-	    free(p1);
-	}
-
-	/*
-	 * All the children were made ok. Now cmgn->mtime contains the
-	 * modification time of the newest child, we need to find out if we
-	 * exist and when we were modified last. The criteria for datedness
-	 * are defined by the Make_OODate function.
-	 */
-	if (DEBUG(MAKE)) {
-	    fprintf(debug_file, "Examining %s...", gn->name);
-	}
-	if (! Make_OODate(gn)) {
-	    gn->made = UPTODATE;
-	    if (DEBUG(MAKE)) {
-		fprintf(debug_file, "up-to-date.\n");
-	    }
-	    goto cohorts;
-	} else if (DEBUG(MAKE)) {
-	    fprintf(debug_file, "out-of-date.\n");
-	}
-
-	/*
-	 * If the user is just seeing if something is out-of-date, exit now
-	 * to tell him/her "yes".
-	 */
-	if (queryFlag) {
-	    exit(1);
-	}
-
-	/*
-	 * We need to be re-made. We also have to make sure we've got a $?
-	 * variable. To be nice, we also define the $> variable using
-	 * Make_DoAllVar().
-	 */
-	Make_DoAllVar(gn);
-
-	/*
-	 * Alter our type to tell if errors should be ignored or things
-	 * should not be printed so CompatRunCommand knows what to do.
-	 */
-	if (Targ_Ignore(gn)) {
-	    gn->type |= OP_IGNORE;
-	}
-	if (Targ_Silent(gn)) {
-	    gn->type |= OP_SILENT;
-	}
-
-	if (Job_CheckCommands(gn, Fatal)) {
-	    /*
-	     * Our commands are ok, but we still have to worry about the -t
-	     * flag...
-	     */
-	    if (!touchFlag || (gn->type & OP_MAKE)) {
-		curTarg = gn;
+Compat_Make(void *gnp, void *pgnp) {
+    GNode *gn = (GNode *) gnp;
+    GNode *pgn = (GNode *) pgnp;
+
+    if (!shellName)        /* we came here from jobs */
+        Shell_Init();
+    if (gn->made == __UNMADE && (gn == pgn || (pgn->type & OP_MADE) == 0)) {
+        /*
+         * First mark ourselves to be made, then apply whatever transformations
+         * the suffix module thinks are necessary. Once that's done, we can
+         * descend and make all our children. If any of them has an error
+         * but the -k flag was given, our 'make' field will be set FALSE again.
+         * This is our signal to not attempt to do anything but abort our
+         * parent as well.
+         */
+        gn->flags |= REMAKE;
+        gn->made = __BEINGMADE;
+        if ((gn->type & OP_MADE) == 0)
+            Suff_FindDeps(gn);
+        Lst_ForEach(gn->children, Compat_Make, gn);
+        if ((gn->flags & REMAKE) == 0) {
+            gn->made = __ABORTED;
+            pgn->flags &= ~REMAKE;
+            goto cohorts;
+        }
+
+        if (Lst_Member(gn->iParents, pgn) != NULL) {
+            char *p1;
+            Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
+            free(p1);
+        }
+
+        /*
+         * All the children were made ok. Now cmgn->mtime contains the
+         * modification time of the newest child, we need to find out if we
+         * exist and when we were modified last. The criteria for datedness
+         * are defined by the Make_OODate function.
+         */
+        if (DEBUG(MAKE)) {
+            fprintf(debug_file, "Examining %s...", gn->name);
+        }
+        if (!Make_OODate(gn)) {
+            gn->made = __UPTODATE;
+            if (DEBUG(MAKE)) {
+                fprintf(debug_file, "up-to-date.\n");
+            }
+            goto cohorts;
+        } else if (DEBUG(MAKE)) {
+            fprintf(debug_file, "out-of-date.\n");
+        }
+
+        /*
+         * If the user is just seeing if something is out-of-date, exit now
+         * to tell him/her "yes".
+         */
+        if (queryFlag) {
+            exit(1);
+        }
+
+        /*
+         * We need to be re-made. We also have to make sure we've got a $?
+         * variable. To be nice, we also define the $> variable using
+         * Make_DoAllVar().
+         */
+        Make_DoAllVar(gn);
+
+        /*
+         * Alter our type to tell if errors should be ignored or things
+         * should not be printed so CompatRunCommand knows what to do.
+         */
+        if (Targ_Ignore(gn)) {
+            gn->type |= OP_IGNORE;
+        }
+        if (Targ_Silent(gn)) {
+            gn->type |= OP_SILENT;
+        }
+
+        if (Job_CheckCommands(gn, Fatal)) {
+            /*
+             * Our commands are ok, but we still have to worry about the -t
+             * flag...
+             */
+            if (!touchFlag || (gn->type & OP_MAKE)) {
+                curTarg = gn;
 #ifdef USE_META
-		if (useMeta && !NoExecute(gn)) {
-		    meta_job_start(NULL, gn);
-		}
+                if (useMeta && !NoExecute(gn)) {
+                    meta_job_start(NULL, gn);
+                }
 #endif
-		Lst_ForEach(gn->commands, CompatRunCommand, gn);
-		curTarg = NULL;
-	    } else {
-		Job_Touch(gn, gn->type & OP_SILENT);
-	    }
-	} else {
-	    gn->made = ERROR;
-	}
+                Lst_ForEach(gn->commands, CompatRunCommand, gn);
+                curTarg = NULL;
+            } else {
+                Job_Touch(gn, gn->type & OP_SILENT);
+            }
+        } else {
+            gn->made = __ERROR;
+        }
 #ifdef USE_META
-	if (useMeta && !NoExecute(gn)) {
-	    if (meta_job_finish(NULL) != 0)
-		gn->made = ERROR;
-	}
+        if (useMeta && !NoExecute(gn)) {
+            if (meta_job_finish(NULL) != 0)
+            gn->made = __ERROR;
+        }
 #endif

-	if (gn->made != ERROR) {
-	    /*
-	     * If the node was made successfully, mark it so, update
-	     * its modification time and timestamp all its parents. Note
-	     * that for .ZEROTIME targets, the timestamping isn't done.
-	     * This is to keep its state from affecting that of its parent.
-	     */
-	    gn->made = MADE;
-	    pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0;
-	    if (!(gn->type & OP_EXEC)) {
-		pgn->flags |= CHILDMADE;
-		Make_TimeStamp(pgn, gn);
-	    }
-	} else if (keepgoing) {
-	    pgn->flags &= ~REMAKE;
-	} else {
-	    PrintOnError(gn, "\nStop.");
-	    exit(1);
-	}
-    } else if (gn->made == ERROR) {
-	/*
-	 * Already had an error when making this beastie. Tell the parent
-	 * to abort.
-	 */
-	pgn->flags &= ~REMAKE;
+        if (gn->made != __ERROR) {
+            /*
+             * If the node was made successfully, mark it so, update
+             * its modification time and timestamp all its parents. Note
+             * that for .ZEROTIME targets, the timestamping isn't done.
+             * This is to keep its state from affecting that of its parent.
+             */
+            gn->made = __MADE;
+            pgn->flags |= Make_Recheck(gn) == 0 ? FORCE : 0;
+            if (!(gn->type & OP_EXEC)) {
+                pgn->flags |= CHILDMADE;
+                Make_TimeStamp(pgn, gn);
+            }
+        } else if (keepgoing) {
+            pgn->flags &= ~REMAKE;
+        } else {
+            PrintOnError(gn, "\nStop.");
+            exit(1);
+        }
+    } else if (gn->made == __ERROR) {
+        /*
+         * Already had an error when making this beastie. Tell the parent
+         * to abort.
+         */
+        pgn->flags &= ~REMAKE;
     } else {
-	if (Lst_Member(gn->iParents, pgn) != NULL) {
-	    char *p1;
-	    Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
-	    free(p1);
-	}
-	switch(gn->made) {
-	    case BEINGMADE:
-		Error("Graph cycles through %s", gn->name);
-		gn->made = ERROR;
-		pgn->flags &= ~REMAKE;
-		break;
-	    case MADE:
-		if ((gn->type & OP_EXEC) == 0) {
-		    pgn->flags |= CHILDMADE;
-		    Make_TimeStamp(pgn, gn);
-		}
-		break;
-	    case UPTODATE:
-		if ((gn->type & OP_EXEC) == 0) {
-		    Make_TimeStamp(pgn, gn);
-		}
-		break;
-	    default:
-		break;
-	}
+        if (Lst_Member(gn->iParents, pgn) != NULL) {
+            char *p1;
+            Var_Set(IMPSRC, Var_Value(TARGET, gn, &p1), pgn, 0);
+            free(p1);
+        }
+        switch (gn->made) {
+            case __BEINGMADE:
+                Error("Graph cycles through %s", gn->name);
+                gn->made = __ERROR;
+                pgn->flags &= ~REMAKE;
+                break;
+            case __MADE:
+                if ((gn->type & OP_EXEC) == 0) {
+                    pgn->flags |= CHILDMADE;
+                    Make_TimeStamp(pgn, gn);
+                }
+                break;
+            case __UPTODATE:
+                if ((gn->type & OP_EXEC) == 0) {
+                    Make_TimeStamp(pgn, gn);
+                }
+                break;
+            default:
+                break;
+        }
     }

-cohorts:
+    cohorts:
     Lst_ForEach(gn->cohorts, Compat_Make, pgnp);
@@ -685,3 +751,3 @@ cohorts:
 }
-
+
 /*-
@@ -703,21 +769,22 @@ cohorts:
 void
-Compat_Run(Lst targs)
-{
-    GNode   	  *gn = NULL;/* Current root target */
-    int	    	  errors;   /* Number of targets not remade due to errors */
+Compat_Run(Lst targs) {
+    GNode *gn = NULL;/* Current root target */
+    int errors;   /* Number of targets not remade due to errors */

     if (!shellName)
-	Shell_Init();
+        Shell_Init();

     if (bmake_signal(SIGINT, SIG_IGN) != SIG_IGN) {
-	bmake_signal(SIGINT, CompatInterrupt);
+        bmake_signal(SIGINT, CompatInterrupt);
     }
     if (bmake_signal(SIGTERM, SIG_IGN) != SIG_IGN) {
-	bmake_signal(SIGTERM, CompatInterrupt);
+        bmake_signal(SIGTERM, CompatInterrupt);
     }
+#if defined(SIGHUP)
     if (bmake_signal(SIGHUP, SIG_IGN) != SIG_IGN) {
-	bmake_signal(SIGHUP, CompatInterrupt);
+    bmake_signal(SIGHUP, CompatInterrupt);
     }
+#endif
     if (bmake_signal(SIGQUIT, SIG_IGN) != SIG_IGN) {
-	bmake_signal(SIGQUIT, CompatInterrupt);
+        bmake_signal(SIGQUIT, CompatInterrupt);
     }
@@ -731,6 +798,6 @@ Compat_Run(Lst targs)
     if (!queryFlag) {
-	gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
-	if (gn != NULL) {
-	    Compat_Make(gn, gn);
-            if (gn->made == ERROR) {
+        gn = Targ_FindNode(".BEGIN", TARG_NOCREATE);
+        if (gn != NULL) {
+            Compat_Make(gn, gn);
+            if (gn->made == __ERROR) {
                 PrintOnError(gn, "\nStop.");
@@ -738,3 +805,3 @@ Compat_Run(Lst targs)
             }
-	}
+        }
     }
@@ -758,12 +825,12 @@ Compat_Run(Lst targs)
     errors = 0;
-    while (!Lst_IsEmpty (targs)) {
-	gn = (GNode *)Lst_DeQueue(targs);
-	Compat_Make(gn, gn);
-
-	if (gn->made == UPTODATE) {
-	    printf("`%s' is up to date.\n", gn->name);
-	} else if (gn->made == ABORTED) {
-	    printf("`%s' not remade because of errors.\n", gn->name);
-	    errors += 1;
-	}
+    while (!Lst_IsEmpty(targs)) {
+        gn = (GNode *) Lst_DeQueue(targs);
+        Compat_Make(gn, gn);
+
+        if (gn->made == __UPTODATE) {
+            printf("`%s' is up to date.\n", gn->name);
+        } else if (gn->made == __ABORTED) {
+            printf("`%s' not remade because of errors.\n", gn->name);
+            errors += 1;
+        }
     }
@@ -774,7 +841,7 @@ Compat_Run(Lst targs)
     if (errors == 0) {
-	Compat_Make(ENDNode, ENDNode);
-	if (gn->made == ERROR) {
-	    PrintOnError(gn, "\nStop.");
-	    exit(1);
-	}
+        Compat_Make(ENDNode, ENDNode);
+        if (gn->made == __ERROR) {
+            PrintOnError(gn, "\nStop.");
+            exit(1);
+        }
     }
diff --git a/config.h.in b/config.h.in
index 82e7e99..f268639 100644
--- a/config.h.in
+++ b/config.h.in
@@ -11,2 +11,5 @@

+/* Define to 1 if you have the `alloca' function. */
+#undef HAVE_ALLOCA
+
 /* Define to 1 if you have the <ar.h> header file. */
@@ -14,2 +17,11 @@

+/* Define to 1 if you have the `atoll' function. */
+#undef HAVE_ATOLL
+
+/* Define to 1 if you have the `canonicalize_file_name' function. */
+#undef HAVE_CANONICALIZE_FILE_NAME
+
+/* Define to 1 if you have the `chown' function. */
+#undef HAVE_CHOWN
+
 /* Define to 1 if you have the declaration of `sys_siglist', and to 0 if you
@@ -28,2 +40,11 @@

+/* Define to 1 if you have the `dup2' function. */
+#undef HAVE_DUP2
+
+/* Define to 1 if you have the `dup3' function. */
+#undef HAVE_DUP3
+
+/* Define to 1 if you have the `endusershell' function. */
+#undef HAVE_ENDUSERSHELL
+
 /* Define to 1 if you have the `err' function. */
@@ -37,2 +58,20 @@

+/* Define to 1 if you have the `euidaccess' function. */
+#undef HAVE_EUIDACCESS
+
+/* Define to 1 if you have the `faccessat' function. */
+#undef HAVE_FACCESSAT
+
+/* Define to 1 if you have the `fchdir' function. */
+#undef HAVE_FCHDIR
+
+/* Define to 1 if you have the `fchmodat' function. */
+#undef HAVE_FCHMODAT
+
+/* Define to 1 if you have the `fchownat' function. */
+#undef HAVE_FCHOWNAT
+
+/* Define to 1 if you have the `fcntl' function. */
+#undef HAVE_FCNTL
+
 /* Define to 1 if you have the <fcntl.h> header file. */
@@ -40,2 +79,5 @@

+/* Define to 1 if you have the `fdatasync' function. */
+#undef HAVE_FDATASYNC
+
 /* Define to 1 if you have the `fork' function. */
@@ -43,2 +85,14 @@

+/* Define to 1 if you have the `fstatat' function. */
+#undef HAVE_FSTATAT
+
+/* Define to 1 if you have the `fsync' function. */
+#undef HAVE_FSYNC
+
+/* Define to 1 if you have the `ftruncate' function. */
+#undef HAVE_FTRUNCATE
+
+/* Define to 1 if you have the `futimens' function. */
+#undef HAVE_FUTIMENS
+
 /* Define to 1 if you have the `getcwd' function. */
@@ -46,2 +100,8 @@

+/* Define to 1 if you have the `getdomainname' function. */
+#undef HAVE_GETDOMAINNAME
+
+/* Define to 1 if you have the `getdtablesize' function. */
+#undef HAVE_GETDTABLESIZE
+
 /* Define to 1 if you have the `getenv' function. */
@@ -49,2 +109,17 @@

+/* Define to 1 if you have the `getgroups' function. */
+#undef HAVE_GETGROUPS
+
+/* Define to 1 if you have the `gethostname' function. */
+#undef HAVE_GETHOSTNAME
+
+/* Define to 1 if you have the `getloadavg' function. */
+#undef HAVE_GETLOADAVG
+
+/* Define to 1 if you have the `getlogin' function. */
+#undef HAVE_GETLOGIN
+
+/* Define to 1 if you have the `getlogin_r' function. */
+#undef HAVE_GETLOGIN_R
+
 /* Define to 1 if you have the `getopt' function. */
@@ -52,2 +127,17 @@

+/* Define to 1 if you have the `getpass' function. */
+#undef HAVE_GETPASS
+
+/* Define to 1 if you have the `getppid' function. */
+#undef HAVE_GETPPID
+
+/* Define to 1 if you have the `getrusage' function. */
+#undef HAVE_GETRUSAGE
+
+/* Define to 1 if you have the `getsubopt' function. */
+#undef HAVE_GETSUBOPT
+
+/* Define to 1 if you have the `getusershell' function. */
+#undef HAVE_GETUSERSHELL
+
 /* Define to 1 if you have the `getwd' function. */
@@ -55,2 +145,14 @@

+/* Define to 1 if you have the `grantpt' function. */
+#undef HAVE_GRANTPT
+
+/* Define to 1 if you have the `group_member' function. */
+#undef HAVE_GROUP_MEMBER
+
+/* Define to 1 if you have the `initstate' function. */
+#undef HAVE_INITSTATE
+
+/* Define to 1 if you have the `initstate_r' function. */
+#undef HAVE_INITSTATE_R
+
 /* Define to 1 if you have the <inttypes.h> header file. */
@@ -58,2 +160,5 @@

+/* Define to 1 if you have the `kill' function. */
+#undef HAVE_KILL
+
 /* Define to 1 if you have the `killpg' function. */
@@ -61,2 +166,8 @@

+/* Define to 1 if you have the `lchmod' function. */
+#undef HAVE_LCHMOD
+
+/* Define to 1 if you have the `lchown' function. */
+#undef HAVE_LCHOWN
+
 /* Define to 1 if you have the <libgen.h> header file. */
@@ -67,2 +178,11 @@

+/* Define to 1 if you have the `link' function. */
+#undef HAVE_LINK
+
+/* Define to 1 if you have the `linkat' function. */
+#undef HAVE_LINKAT
+
+/* Define to 1 if you have the `lstat' function. */
+#undef HAVE_LSTAT
+
 /* Define to 1 if you have the <memory.h> header file. */
@@ -70,2 +190,32 @@

+/* Define to 1 if you have the `mkdirat' function. */
+#undef HAVE_MKDIRAT
+
+/* Define to 1 if you have the `mkdtemp' function. */
+#undef HAVE_MKDTEMP
+
+/* Define to 1 if you have the `mkfifo' function. */
+#undef HAVE_MKFIFO
+
+/* Define to 1 if you have the `mkfifoat' function. */
+#undef HAVE_MKFIFOAT
+
+/* Define to 1 if you have the `mknod' function. */
+#undef HAVE_MKNOD
+
+/* Define to 1 if you have the `mknodat' function. */
+#undef HAVE_MKNODAT
+
+/* Define to 1 if you have the `mkostemp' function. */
+#undef HAVE_MKOSTEMP
+
+/* Define to 1 if you have the `mkostemps' function. */
+#undef HAVE_MKOSTEMPS
+
+/* Define to 1 if you have the `mkstemp' function. */
+#undef HAVE_MKSTEMP
+
+/* Define to 1 if you have the `mkstemps' function. */
+#undef HAVE_MKSTEMPS
+
 /* Define to 1 if you have the `mmap' function. */
@@ -76,2 +226,5 @@

+/* Define to 1 if you have the `openat' function. */
+#undef HAVE_OPENAT
+
 /* Define to 1 if you have the <paths.h> header file. */
@@ -79,2 +232,11 @@

+/* Define to 1 if you have the `pipe' function. */
+#undef HAVE_PIPE
+
+/* Define to 1 if you have the `pipe2' function. */
+#undef HAVE_PIPE2
+
+/* Define to 1 if you have the `poll' function. */
+#undef HAVE_POLL
+
 /* Define to 1 if you have the <poll.h> header file. */
@@ -82,2 +244,17 @@

+/* Define to 1 if you have the `posix_openpt' function. */
+#undef HAVE_POSIX_OPENPT
+
+/* Define to 1 if you have the `pread' function. */
+#undef HAVE_PREAD
+
+/* Define to 1 if you have the `pthread_sigmask' function. */
+#undef HAVE_PTHREAD_SIGMASK
+
+/* Define to 1 if you have the `ptsname' function. */
+#undef HAVE_PTSNAME
+
+/* Define to 1 if you have the `ptsname_r' function. */
+#undef HAVE_PTSNAME_R
+
 /* Define to 1 if you have the `putenv' function. */
@@ -85,2 +262,17 @@

+/* Define to 1 if you have the `pwrite' function. */
+#undef HAVE_PWRITE
+
+/* Define to 1 if you have the `qsort_r' function. */
+#undef HAVE_QSORT_R
+
+/* Define to 1 if you have the `raise' function. */
+#undef HAVE_RAISE
+
+/* Define to 1 if you have the `random' function. */
+#undef HAVE_RANDOM
+
+/* Define to 1 if you have the `random_r' function. */
+#undef HAVE_RANDOM_R
+
 /* Define to 1 if you have the <ranlib.h> header file. */
@@ -88,2 +280,11 @@

+/* Define to 1 if you have the `readlink' function. */
+#undef HAVE_READLINK
+
+/* Define to 1 if you have the `readlinkat' function. */
+#undef HAVE_READLINKAT
+
+/* Define to 1 if you have the `reallocarray' function. */
+#undef HAVE_REALLOCARRAY
+
 /* Define to 1 if you have the `realpath' function. */
@@ -91,2 +292,20 @@

+/* Define to 1 if you have the `regcomp' function. */
+#undef HAVE_REGCOMP
+
+/* Define to 1 if you have the `regerror' function. */
+#undef HAVE_REGERROR
+
+/* Define to 1 if you have the `regexec' function. */
+#undef HAVE_REGEXEC
+
+/* Define to 1 if you have the `regfree' function. */
+#undef HAVE_REGFREE
+
+/* Define to 1 if you have the `rpmatch' function. */
+#undef HAVE_RPMATCH
+
+/* Define to 1 if you have the `secure_getenv' function. */
+#undef HAVE_SECURE_GETENV
+
 /* Define to 1 if you have the `select' function. */
@@ -97,2 +316,5 @@

+/* Define to 1 if you have the `sethostname' function. */
+#undef HAVE_SETHOSTNAME
+
 /* Define to 1 if you have the `setpgid' function. */
@@ -100,2 +322,5 @@

+/* Define to 1 if you have the `setpgrp' function. */
+#undef HAVE_SETPGRP
+
 /* Define to 1 if you have the `setsid' function. */
@@ -103,2 +328,11 @@

+/* Define to 1 if you have the `setstate' function. */
+#undef HAVE_SETSTATE
+
+/* Define to 1 if you have the `setstate_r' function. */
+#undef HAVE_SETSTATE_R
+
+/* Define to 1 if you have the `setusershell' function. */
+#undef HAVE_SETUSERSHELL
+
 /* Define to 1 if you have the `sigaction' function. */
@@ -106,2 +340,26 @@

+/* Define to 1 if you have the `sigaddset' function. */
+#undef HAVE_SIGADDSET
+
+/* Define to 1 if you have the `sigdelset' function. */
+#undef HAVE_SIGDELSET
+
+/* Define to 1 if you have the `sigemptyset' function. */
+#undef HAVE_SIGEMPTYSET
+
+/* Define to 1 if you have the `sigfillset' function. */
+#undef HAVE_SIGFILLSET
+
+/* Define to 1 if you have the `sigismember' function. */
+#undef HAVE_SIGISMEMBER
+
+/* Define to 1 if you have the `signal' function. */
+#undef HAVE_SIGNAL
+
+/* Define to 1 if you have the `sigpending' function. */
+#undef HAVE_SIGPENDING
+
+/* Define to 1 if you have the `sigprocmask' function. */
+#undef HAVE_SIGPROCMASK
+
 /* Define to 1 if you have the `sigvec' function. */
@@ -109,2 +367,5 @@

+/* Define to 1 if you have the `sleep' function. */
+#undef HAVE_SLEEP
+
 /* Define to 1 if you have the `snprintf' function. */
@@ -112,2 +373,8 @@

+/* Define to 1 if you have the `srandom' function. */
+#undef HAVE_SRANDOM
+
+/* Define to 1 if you have the `srandom_r' function. */
+#undef HAVE_SRANDOM_R
+
 /* Define to 1 if you have the <stdint.h> header file. */
@@ -145,3 +412,9 @@

-/* Define to 1 if `struct stat' is a member of `st_rdev'. */
+/* Define to 1 if you have the `strtoll' function. */
+#undef HAVE_STRTOLL
+
+/* Define to 1 if you have the `strtoull' function. */
+#undef HAVE_STRTOULL
+
+/* Define to 1 if `st_rdev' is a member of `struct stat'. */
 #undef HAVE_STRUCT_STAT_ST_RDEV
@@ -152,2 +425,8 @@

+/* Define to 1 if you have the `symlink' function. */
+#undef HAVE_SYMLINK
+
+/* Define to 1 if you have the `symlinkat' function. */
+#undef HAVE_SYMLINKAT
+
 /* Define to 1 if you have the `sysctl' function. */
@@ -169,2 +448,5 @@

+/* Define to 1 if you have the <sys/resource.h> header file. */
+#undef HAVE_SYS_RESOURCE_H
+
 /* Define to 1 if you have the <sys/select.h> header file. */
@@ -190,5 +472,17 @@

-/* Define to 1 if you have <sys/wait.h> that is POSIX.1 compatible. */
+/* Define to 1 if you have the <sys/utsname.h> header file. */
+#undef HAVE_SYS_UTSNAME_H
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
 #undef HAVE_SYS_WAIT_H

+/* Define to 1 if you have the `truncate' function. */
+#undef HAVE_TRUNCATE
+
+/* Define to 1 if you have the `ttyname_r' function. */
+#undef HAVE_TTYNAME_R
+
+/* Define to 1 if you have the `uname' function. */
+#undef HAVE_UNAME
+
 /* Define to 1 if you have the <unistd.h> header file. */
@@ -196,2 +490,8 @@

+/* Define to 1 if you have the `unlinkat' function. */
+#undef HAVE_UNLINKAT
+
+/* Define to 1 if you have the `unlockpt' function. */
+#undef HAVE_UNLOCKPT
+
 /* Define to 1 if you have the `unsetenv' function. */
@@ -199,2 +499,8 @@

+/* Define to 1 if you have the `usleep' function. */
+#undef HAVE_USLEEP
+
+/* Define to 1 if you have the `utimensat' function. */
+#undef HAVE_UTIMENSAT
+
 /* Define to 1 if you have the <utime.h> header file. */
@@ -214,2 +520,5 @@

+/* Define to 1 if you have the `wait' function. */
+#undef HAVE_WAIT
+
 /* Define to 1 if you have the `wait3' function. */
@@ -235,2 +544,5 @@

+/* Define to 1 if you have the `_Exit' function. */
+#undef HAVE__EXIT
+
 /* define if your compiler has __attribute__ */
@@ -326,2 +638,6 @@

+/* Define to the type of a signed integer type of width exactly 32 bits if
+   such a type exists and the standard includes do not define it. */
+#undef int32_t
+
 /* Define to `int' if <sys/types.h> does not define. */
diff --git a/configure b/configure
index 1ce8dfe..42ac2d4 100755
--- a/configure
+++ b/configure
@@ -2,3 +2,3 @@
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.64 for bmake 20171126.
+# Generated by GNU Autoconf 2.69 for bmake 20171126.
 #
@@ -6,5 +6,5 @@
 #
-# Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
-# 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009 Free Software
-# Foundation, Inc.
+#
+# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc.
+#
 #
@@ -91,2 +91,3 @@ IFS=" ""	$as_nl"
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
@@ -135,2 +136,27 @@ export LANGUAGE

+# Use a proper internal environment variable to ensure we don't fall
+  # into an infinite loop, continuously re-executing ourselves.
+  if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then
+    _as_can_reexec=no; export _as_can_reexec;
+    # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+as_fn_exit 255
+  fi
+  # We don't want this to propagate to other subprocesses.
+          { _as_can_reexec=; unset _as_can_reexec;}
 if test "x$CONFIG_SHELL" = x; then
@@ -168,3 +194,4 @@ else
 fi
-test x\$exitcode = x0 || exit 1"
+test x\$exitcode = x0 || exit 1
+test -x / || exit 1"
   as_suggested="  as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO
@@ -213,10 +240,21 @@ IFS=$as_save_IFS
       if test "x$CONFIG_SHELL" != x; then :
-  # We cannot yet assume a decent shell, so we have to provide a
-	# neutralization value for shells without unset; and this also
-	# works around shells that cannot unset nonexistent variables.
-	BASH_ENV=/dev/null
-	ENV=/dev/null
-	(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
-	export CONFIG_SHELL
-	exec "$CONFIG_SHELL" "$as_myself" ${1+"$@"}
+  export CONFIG_SHELL
+             # We cannot yet assume a decent shell, so we have to provide a
+# neutralization value for shells without unset; and this also
+# works around shells that cannot unset nonexistent variables.
+# Preserve -v and -x to the replacement shell.
+BASH_ENV=/dev/null
+ENV=/dev/null
+(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV
+case $- in # ((((
+  *v*x* | *x*v* ) as_opts=-vx ;;
+  *v* ) as_opts=-v ;;
+  *x* ) as_opts=-x ;;
+  * ) as_opts= ;;
+esac
+exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"}
+# Admittedly, this is quite paranoid, since all the known shells bail
+# out after a failed `exec'.
+$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2
+exit 255
 fi
@@ -319,3 +357,3 @@ $as_echo X"$as_dir" |
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"

@@ -323,2 +361,10 @@ $as_echo X"$as_dir" |
 } # as_fn_mkdir_p
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
 # as_fn_append VAR VALUE
@@ -359,15 +405,15 @@ fi # as_fn_arith

-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
@@ -444,2 +490,6 @@ as_cr_alnum=$as_cr_Letters$as_cr_digits

+  # If we had to re-execute with $CONFIG_SHELL, we're ensured to have
+  # already done that, so ensure we don't try to do so again and fall
+  # in an infinite loop.  This has already happened in practice.
+  _as_can_reexec=no; export _as_can_reexec
   # Don't try to exec as it changes $[0], causing all sort of problems
@@ -478,5 +528,5 @@ if (echo >conf$$.file) 2>/dev/null; then
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
@@ -484,6 +534,6 @@ if (echo >conf$$.file) 2>/dev/null; then
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
@@ -499,24 +549,4 @@ fi

-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-	test -d "$1/.";
-      else
-	case $1 in #(
-	-*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p

@@ -529,6 +559,7 @@ as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'"

-exec 7<&0 </dev/null 6>&1
+test -n "$DJDIR" || exec 7<&0 </dev/null
+exec 6>&1

 # Name of the host.
-# hostname on some systems (SVR3.2, Linux) returns a bogus exit status,
+# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status,
 # so uname gets run too.
@@ -745,4 +776,5 @@ do
   case $ac_option in
-  *=*)	ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
-  *)	ac_optarg=yes ;;
+  *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;;
+  *=)   ac_optarg= ;;
+  *)    ac_optarg=yes ;;
   esac
@@ -791,3 +823,3 @@ do
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
@@ -817,3 +849,3 @@ do
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid feature name: $ac_useropt"
+      as_fn_error $? "invalid feature name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
@@ -1021,3 +1053,3 @@ do
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
@@ -1037,3 +1069,3 @@ do
     expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null &&
-      as_fn_error "invalid package name: $ac_useropt"
+      as_fn_error $? "invalid package name: $ac_useropt"
     ac_useropt_orig=$ac_useropt
@@ -1067,4 +1099,4 @@ do

-  -*) as_fn_error "unrecognized option: \`$ac_option'
-Try \`$0 --help' for more information."
+  -*) as_fn_error $? "unrecognized option: \`$ac_option'
+Try \`$0 --help' for more information"
     ;;
@@ -1076,3 +1108,3 @@ Try \`$0 --help' for more information."
       '' | [0-9]* | *[!_$as_cr_alnum]* )
-      as_fn_error "invalid variable name: \`$ac_envvar'" ;;
+      as_fn_error $? "invalid variable name: \`$ac_envvar'" ;;
     esac
@@ -1086,3 +1118,3 @@ Try \`$0 --help' for more information."
       $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2
-    : ${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}
+    : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}"
     ;;
@@ -1094,3 +1126,3 @@ if test -n "$ac_prev"; then
   ac_option=--`echo $ac_prev | sed 's/_/-/g'`
-  as_fn_error "missing argument to $ac_option"
+  as_fn_error $? "missing argument to $ac_option"
 fi
@@ -1100,3 +1132,3 @@ if test -n "$ac_unrecognized_opts"; then
     no) ;;
-    fatal) as_fn_error "unrecognized options: $ac_unrecognized_opts" ;;
+    fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;;
     *)     $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;;
@@ -1123,3 +1155,3 @@ do
   esac
-  as_fn_error "expected an absolute directory name for --$ac_var: $ac_val"
+  as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val"
 done
@@ -1137,4 +1169,2 @@ if test "x$host_alias" != x; then
     cross_compiling=maybe
-    $as_echo "$as_me: WARNING: If you wanted to set the --build type, don't use --host.
-    If a cross compiler is detected then cross compile mode will be used." >&2
   elif test "x$build_alias" != "x$host_alias"; then
@@ -1153,5 +1183,5 @@ ac_ls_di=`ls -di .` &&
 ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` ||
-  as_fn_error "working directory cannot be determined"
+  as_fn_error $? "working directory cannot be determined"
 test "X$ac_ls_di" = "X$ac_pwd_ls_di" ||
-  as_fn_error "pwd does not report name of working directory"
+  as_fn_error $? "pwd does not report name of working directory"

@@ -1194,3 +1224,3 @@ if test ! -r "$srcdir/$ac_unique_file"; then
   test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .."
-  as_fn_error "cannot find sources ($ac_unique_file) in $srcdir"
+  as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir"
 fi
@@ -1198,3 +1228,3 @@ ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work"
 ac_abs_confdir=`(
-	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error "$ac_msg"
+	cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg"
 	pwd)`
@@ -1238,3 +1268,3 @@ Configuration:
   -V, --version           display version information and exit
-  -q, --quiet, --silent   do not print \`checking...' messages
+  -q, --quiet, --silent   do not print \`checking ...' messages
       --cache-file=FILE   cache test results in FILE [disabled]
@@ -1320,3 +1350,3 @@ Some influential environment variables:
   LIBS        libraries to pass to the linker, e.g. -l<library>
-  CPPFLAGS    C/C++/Objective C preprocessor flags, e.g. -I<include dir> if
+  CPPFLAGS    (Objective) C/C++ preprocessor flags, e.g. -I<include dir> if
               you have headers in a nonstandard directory <include dir>
@@ -1391,5 +1421,5 @@ if $ac_init_version; then
 bmake configure 20171126
-generated by GNU Autoconf 2.64
+generated by GNU Autoconf 2.69

-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This configure script is free software; the Free Software Foundation
@@ -1437,4 +1467,4 @@ sed 's/^/| /' conftest.$ac_ext >&5
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval

@@ -1463,3 +1493,3 @@ $as_echo "$ac_try_echo"; } >&5
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; } >/dev/null && {
+  test $ac_status = 0; } > conftest.i && {
 	 test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
@@ -1474,4 +1504,4 @@ sed 's/^/| /' conftest.$ac_ext >&5
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval

@@ -1487,6 +1517,6 @@ ac_fn_c_check_header_mongrel ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  if eval \${$3+:} false; then :
   { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1526,3 +1556,3 @@ else
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5
@@ -1549,7 +1579,5 @@ $as_echo "$as_me: WARNING: $2:     section \"Present But Cannot Be Compiled\"" >
 $as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;}
-( cat <<\_ASBOX
-## ----------------------------- ##
+( $as_echo "## ----------------------------- ##
 ## Report this to sjg@NetBSD.org ##
-## ----------------------------- ##
-_ASBOX
+## ----------------------------- ##"
      ) | sed "s/^/$as_me: WARNING:     /" >&2
@@ -1559,3 +1587,3 @@ esac
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1568,3 +1596,3 @@ $as_echo "$ac_res" >&6; }
 fi
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

@@ -1609,4 +1637,4 @@ fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval

@@ -1623,3 +1651,3 @@ ac_fn_c_check_header_compile ()
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1641,3 +1669,3 @@ eval ac_res=\$$3
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

@@ -1672,3 +1700,3 @@ $as_echo "$ac_try_echo"; } >&5
 	 test "$cross_compiling" = yes ||
-	 $as_test_x conftest$ac_exeext
+	 test -x conftest$ac_exeext
        }; then :
@@ -1686,4 +1714,4 @@ fi
   rm -rf conftest.dSYM conftest_ipa8_conftest.oo
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
-  return $ac_retval
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+  as_fn_set_status $ac_retval

@@ -1691,2 +1719,78 @@ fi

+# ac_fn_c_find_intX_t LINENO BITS VAR
+# -----------------------------------
+# Finds a signed integer type with width BITS, setting cache variable VAR
+# accordingly.
+ac_fn_c_find_intX_t ()
+{
+  as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking for int$2_t" >&5
+$as_echo_n "checking for int$2_t... " >&6; }
+if eval \${$3+:} false; then :
+  $as_echo_n "(cached) " >&6
+else
+  eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
+     for ac_type in int$2_t 'int' 'long int' \
+	 'long long int' 'short int' 'signed char'; do
+       cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+	     enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(0 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1))];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+  cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+$ac_includes_default
+	        enum { N = $2 / 2 - 1 };
+int
+main ()
+{
+static int test_array [1 - 2 * !(($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 1)
+		 < ($ac_type) ((((($ac_type) 1 << N) << N) - 1) * 2 + 2))];
+test_array [0] = 0;
+return test_array [0];
+
+  ;
+  return 0;
+}
+_ACEOF
+if ac_fn_c_try_compile "$LINENO"; then :
+
+else
+  case $ac_type in #(
+  int$2_t) :
+    eval "$3=yes" ;; #(
+  *) :
+    eval "$3=\$ac_type" ;;
+esac
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+fi
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+       if eval test \"x\$"$3"\" = x"no"; then :
+
+else
+  break
+fi
+     done
+fi
+eval ac_res=\$$3
+	       { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5
+$as_echo "$ac_res" >&6; }
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno
+
+} # ac_fn_c_find_intX_t
+
 # ac_fn_c_check_type LINENO TYPE VAR INCLUDES
@@ -1700,3 +1804,3 @@ ac_fn_c_check_type ()
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1741,3 +1845,3 @@ eval ac_res=\$$3
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

@@ -1754,3 +1858,3 @@ ac_fn_c_find_uintX_t ()
 $as_echo_n "checking for uint$2_t... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1758,2 +1862,4 @@ else
   eval "$3=no"
+     # Order is important - never check a type that is potentially smaller
+     # than half of the expected target width.
      for ac_type in uint$2_t 'unsigned int' 'unsigned long int' \
@@ -1766,4 +1872,5 @@ main ()
 {
-static int test_array [1 - 2 * !(($ac_type) -1 >> ($2 - 1) == 1)];
-test_array [0] = 0
+static int test_array [1 - 2 * !((($ac_type) -1 >> ($2 / 2 - 1)) >> ($2 / 2 - 1) == 3)];
+test_array [0] = 0;
+return test_array [0];

@@ -1782,4 +1889,3 @@ fi
 rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
-       eval as_val=\$$3
-   if test "x$as_val" = x""no; then :
+       if eval test \"x\$"$3"\" = x"no"; then :

@@ -1793,3 +1899,3 @@ eval ac_res=\$$3
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

@@ -1797,5 +1903,6 @@ $as_echo "$ac_res" >&6; }

-# ac_fn_c_check_decl LINENO SYMBOL VAR
-# ------------------------------------
-# Tests whether SYMBOL is declared, setting cache variable VAR accordingly.
+# ac_fn_c_check_decl LINENO SYMBOL VAR INCLUDES
+# ---------------------------------------------
+# Tests whether SYMBOL is declared in INCLUDES, setting cache variable VAR
+# accordingly.
 ac_fn_c_check_decl ()
@@ -1803,5 +1910,7 @@ ac_fn_c_check_decl ()
   as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $2 is declared" >&5
-$as_echo_n "checking whether $2 is declared... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+  as_decl_name=`echo $2|sed 's/ *(.*//'`
+  as_decl_use=`echo $2|sed -e 's/(/((/' -e 's/)/) 0&/' -e 's/,/) 0& (/g'`
+  { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $as_decl_name is declared" >&5
+$as_echo_n "checking whether $as_decl_name is declared... " >&6; }
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1814,4 +1923,8 @@ main ()
 {
-#ifndef $2
-  (void) $2;
+#ifndef $as_decl_name
+#ifdef __cplusplus
+  (void) $as_decl_use;
+#else
+  (void) $as_decl_name;
+#endif
 #endif
@@ -1832,3 +1945,3 @@ eval ac_res=\$$3
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

@@ -1844,3 +1957,3 @@ ac_fn_c_check_func ()
 $as_echo_n "checking for $2... " >&6; }
-if { as_var=$3; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$3+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1899,3 +2012,3 @@ eval ac_res=\$$3
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

@@ -1912,3 +2025,3 @@ ac_fn_c_check_member ()
 $as_echo_n "checking for $2.$3... " >&6; }
-if { as_var=$4; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$4+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -1956,3 +2069,3 @@ eval ac_res=\$$4
 $as_echo "$ac_res" >&6; }
-  eval $as_lineno_stack; test "x$as_lineno_stack" = x && { as_lineno=; unset as_lineno;}
+  eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno

@@ -1964,3 +2077,3 @@ running configure, to aid debugging if configure makes a mistake.
 It was created by bmake $as_me 20171126, which was
-generated by GNU Autoconf 2.64.  Invocation command line was
+generated by GNU Autoconf 2.69.  Invocation command line was

@@ -2074,7 +2187,5 @@ trap 'exit_status=$?

-    cat <<\_ASBOX
-## ---------------- ##
+    $as_echo "## ---------------- ##
 ## Cache variables. ##
-## ---------------- ##
-_ASBOX
+## ---------------- ##"
     echo
@@ -2112,7 +2223,5 @@ $as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;;

-    cat <<\_ASBOX
-## ----------------- ##
+    $as_echo "## ----------------- ##
 ## Output variables. ##
-## ----------------- ##
-_ASBOX
+## ----------------- ##"
     echo
@@ -2129,7 +2238,5 @@ _ASBOX
     if test -n "$ac_subst_files"; then
-      cat <<\_ASBOX
-## ------------------- ##
+      $as_echo "## ------------------- ##
 ## File substitutions. ##
-## ------------------- ##
-_ASBOX
+## ------------------- ##"
       echo
@@ -2147,7 +2254,5 @@ _ASBOX
     if test -s confdefs.h; then
-      cat <<\_ASBOX
-## ----------- ##
+      $as_echo "## ----------- ##
 ## confdefs.h. ##
-## ----------- ##
-_ASBOX
+## ----------- ##"
       echo
@@ -2206,3 +2311,8 @@ ac_site_file2=NONE
 if test -n "$CONFIG_SITE"; then
-  ac_site_file1=$CONFIG_SITE
+  # We do not want a PATH search for config.site.
+  case $CONFIG_SITE in #((
+    -*)  ac_site_file1=./$CONFIG_SITE;;
+    */*) ac_site_file1=$CONFIG_SITE;;
+    *)   ac_site_file1=./$CONFIG_SITE;;
+  esac
 elif test "x$prefix" != xNONE; then
@@ -2217,3 +2327,3 @@ do
   test "x$ac_site_file" = xNONE && continue
-  if test -r "$ac_site_file"; then
+  if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5
@@ -2221,3 +2331,7 @@ $as_echo "$as_me: loading site script $ac_site_file" >&6;}
     sed 's/^/| /' "$ac_site_file" >&5
-    . "$ac_site_file"
+    . "$ac_site_file" \
+      || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "failed to load site script $ac_site_file
+See \`config.log' for more details" "$LINENO" 5; }
   fi
@@ -2226,5 +2340,5 @@ done
 if test -r "$cache_file"; then
-  # Some versions of bash will fail to source /dev/null (special
-  # files actually), so we avoid doing that.
-  if test -f "$cache_file"; then
+  # Some versions of bash will fail to source /dev/null (special files
+  # actually), so we avoid doing that.  DJGPP emulates it as a regular file.
+  if test /dev/null != "$cache_file" && test -f "$cache_file"; then
     { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5
@@ -2297,3 +2411,3 @@ $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
 $as_echo "$as_me: error: changes in the environment can compromise the build" >&2;}
-  as_fn_error "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
+  as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5
 fi
@@ -2324,3 +2438,3 @@ if test "${with_defshell+set}" = set; then :
   withval=$with_defshell; case "${withval}" in
-yes)   as_fn_error "bad value ${withval} given for bmake DEFSHELL" "$LINENO" 5 ;;
+yes)   as_fn_error $? "bad value ${withval} given for bmake DEFSHELL" "$LINENO" 5 ;;
 no)    ;;
@@ -2342,3 +2456,3 @@ if test "${with_meta+set}" = set; then :
 yes|no) use_meta=${withval};;
-*) as_fn_error "bad value ${withval} given for meta" "$LINENO" 5 ;;
+*) as_fn_error $? "bad value ${withval} given for meta" "$LINENO" 5 ;;
 esac
@@ -2352,3 +2466,3 @@ if test "${with_filemon+set}" = set; then :
 */filemon*) filemon_h="${withval}/filemon.h";;
-*) as_fn_error "bad value ${withval} given for filemon" "$LINENO" 5 ;;
+*) as_fn_error $? "bad value ${withval} given for filemon" "$LINENO" 5 ;;
 esac
@@ -2356,3 +2470,3 @@ else

-OS=`uname -s`
+OS=`uname -s | cut -d_ -f1`
 for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon"
@@ -2387,3 +2501,3 @@ set dummy ${ac_tool_prefix}gcc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2399,3 +2513,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
@@ -2427,3 +2541,3 @@ set dummy gcc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2439,3 +2553,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
@@ -2480,3 +2594,3 @@ set dummy ${ac_tool_prefix}cc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2492,3 +2606,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
@@ -2520,3 +2634,3 @@ set dummy cc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2533,3 +2647,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
@@ -2579,3 +2693,3 @@ set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2591,3 +2705,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
@@ -2623,3 +2737,3 @@ set dummy $ac_prog; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2635,3 +2749,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
@@ -2677,4 +2791,4 @@ test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd'
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }

@@ -2699,4 +2813,4 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
-    rm -f conftest.er1 conftest.err
   fi
+  rm -f conftest.er1 conftest.err
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
@@ -2707,3 +2821,3 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 /* end confdefs.h.  */
-#include <stdio.h>
+
 int
@@ -2711,4 +2825,2 @@ main ()
 {
-FILE *f = fopen ("conftest.out", "w");
- return ferror (f) || fclose (f) != 0;

@@ -2719,3 +2831,3 @@ _ACEOF
 ac_clean_files_save=$ac_clean_files
-ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
+ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out"
 # Try to create an executable without -o first, disregard a.out.
@@ -2723,4 +2835,4 @@ ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out conftest.out"
 # of exeext.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
-$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
+$as_echo_n "checking whether the C compiler works... " >&6; }
 ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'`
@@ -2786,6 +2898,6 @@ else
 fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
-$as_echo "$ac_file" >&6; }
 if test -z "$ac_file"; then :
-  $as_echo "$as_me: failed program was:" >&5
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5
+$as_echo "no" >&6; }
+$as_echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
@@ -2794,50 +2906,16 @@ sed 's/^/| /' conftest.$ac_ext >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-{ as_fn_set_status 77
-as_fn_error "C compiler cannot create executables
-See \`config.log' for more details." "$LINENO" 5; }; }
+as_fn_error 77 "C compiler cannot create executables
+See \`config.log' for more details" "$LINENO" 5; }
+else
+  { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
+$as_echo "yes" >&6; }
 fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5
+$as_echo_n "checking for C compiler default output file name... " >&6; }
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5
+$as_echo "$ac_file" >&6; }
 ac_exeext=$ac_cv_exeext

-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5
-$as_echo_n "checking whether the C compiler works... " >&6; }
-# If not cross compiling, check that we can run a simple program.
-if test "$cross_compiling" != yes; then
-  if { ac_try='./$ac_file'
-  { { case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
-$as_echo "$ac_try_echo"; } >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
-  test $ac_status = 0; }; }; then
-    cross_compiling=no
-  else
-    if test "$cross_compiling" = maybe; then
-	cross_compiling=yes
-    else
-	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
-$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot run C compiled programs.
-If you meant to cross compile, use \`--host'.
-See \`config.log' for more details." "$LINENO" 5; }
-    fi
-  fi
-fi
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5
-$as_echo "yes" >&6; }
-
-rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out conftest.out
+rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out
 ac_clean_files=$ac_clean_files_save
-# Check that the compiler produces executables we can run.  If not, either
-# the compiler is broken, or we cross compile.
-{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
-$as_echo_n "checking whether we are cross compiling... " >&6; }
-{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
-$as_echo "$cross_compiling" >&6; }
-
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5
@@ -2871,6 +2949,6 @@ else
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of executables: cannot compile and link
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of executables: cannot compile and link
+See \`config.log' for more details" "$LINENO" 5; }
 fi
-rm -f conftest$ac_cv_exeext
+rm -f conftest conftest$ac_cv_exeext
 { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5
@@ -2881,5 +2959,64 @@ EXEEXT=$ac_cv_exeext
 ac_exeext=$EXEEXT
+cat confdefs.h - <<_ACEOF >conftest.$ac_ext
+/* end confdefs.h.  */
+#include <stdio.h>
+int
+main ()
+{
+FILE *f = fopen ("conftest.out", "w");
+ return ferror (f) || fclose (f) != 0;
+
+  ;
+  return 0;
+}
+_ACEOF
+ac_clean_files="$ac_clean_files conftest.out"
+# Check that the compiler produces executables we can run.  If not, either
+# the compiler is broken, or we cross compile.
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5
+$as_echo_n "checking whether we are cross compiling... " >&6; }
+if test "$cross_compiling" != yes; then
+  { { ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }
+  if { ac_try='./conftest$ac_cv_exeext'
+  { { case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\""
+$as_echo "$ac_try_echo"; } >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
+  test $ac_status = 0; }; }; then
+    cross_compiling=no
+  else
+    if test "$cross_compiling" = maybe; then
+	cross_compiling=yes
+    else
+	{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5
+$as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
+as_fn_error $? "cannot run C compiled programs.
+If you meant to cross compile, use \`--host'.
+See \`config.log' for more details" "$LINENO" 5; }
+    fi
+  fi
+fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5
+$as_echo "$cross_compiling" >&6; }
+
+rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out
+ac_clean_files=$ac_clean_files_save
 { $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5
 $as_echo_n "checking for suffix of object files... " >&6; }
-if test "${ac_cv_objext+set}" = set; then :
+if ${ac_cv_objext+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2923,4 +3060,4 @@ sed 's/^/| /' conftest.$ac_ext >&5
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "cannot compute suffix of object files: cannot compile
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "cannot compute suffix of object files: cannot compile
+See \`config.log' for more details" "$LINENO" 5; }
 fi
@@ -2934,3 +3071,3 @@ ac_objext=$OBJEXT
 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -2971,3 +3108,3 @@ ac_save_CFLAGS=$CFLAGS
 $as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3049,3 +3186,3 @@ fi
 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3058,4 +3195,3 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
@@ -3157,3 +3293,3 @@ fi
 if test -z "$CPP"; then
-  if test "${ac_cv_prog_CPP+set}" = set; then :
+  if ${ac_cv_prog_CPP+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3187,3 +3323,3 @@ continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext

@@ -3203,3 +3339,3 @@ break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext

@@ -3207,3 +3343,3 @@ done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
@@ -3246,3 +3382,3 @@ continue
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext

@@ -3262,3 +3398,3 @@ break
 fi
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.err conftest.i conftest.$ac_ext

@@ -3266,3 +3402,3 @@ done
 # Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped.
-rm -f conftest.err conftest.$ac_ext
+rm -f conftest.i conftest.err conftest.$ac_ext
 if $ac_preproc_ok; then :
@@ -3272,4 +3408,4 @@ else
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "C preprocessor \"$CPP\" fails sanity check
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "C preprocessor \"$CPP\" fails sanity check
+See \`config.log' for more details" "$LINENO" 5; }
 fi
@@ -3285,3 +3421,3 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 $as_echo_n "checking for grep that handles long lines and -e... " >&6; }
-if test "${ac_cv_path_GREP+set}" = set; then :
+if ${ac_cv_path_GREP+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3299,3 +3435,3 @@ do
       ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_GREP" && $as_test_x "$ac_path_GREP"; } || continue
+      as_fn_executable_p "$ac_path_GREP" || continue
 # Check for GNU ac_path_GREP and select it if it is found.
@@ -3334,3 +3470,3 @@ IFS=$as_save_IFS
   if test -z "$ac_cv_path_GREP"; then
-    as_fn_error "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
@@ -3348,3 +3484,3 @@ $as_echo "$ac_cv_path_GREP" >&6; }
 $as_echo_n "checking for egrep... " >&6; }
-if test "${ac_cv_path_EGREP+set}" = set; then :
+if ${ac_cv_path_EGREP+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3365,3 +3501,3 @@ do
       ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext"
-      { test -f "$ac_path_EGREP" && $as_test_x "$ac_path_EGREP"; } || continue
+      as_fn_executable_p "$ac_path_EGREP" || continue
 # Check for GNU ac_path_EGREP and select it if it is found.
@@ -3400,3 +3536,3 @@ IFS=$as_save_IFS
   if test -z "$ac_cv_path_EGREP"; then
-    as_fn_error "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
+    as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5
   fi
@@ -3415,3 +3551,3 @@ $as_echo "$ac_cv_path_EGREP" >&6; }
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3532,4 +3668,3 @@ ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_include
 "
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
@@ -3545,3 +3680,3 @@ done
   ac_fn_c_check_header_mongrel "$LINENO" "minix/config.h" "ac_cv_header_minix_config_h" "$ac_includes_default"
-if test "x$ac_cv_header_minix_config_h" = x""yes; then :
+if test "x$ac_cv_header_minix_config_h" = xyes; then :
   MINIX=yes
@@ -3567,3 +3702,3 @@ $as_echo "#define _MINIX 1" >>confdefs.h
 $as_echo_n "checking whether it is safe to define __EXTENSIONS__... " >&6; }
-if test "${ac_cv_safe_to_define___extensions__+set}" = set; then :
+if ${ac_cv_safe_to_define___extensions__+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3573,4 +3708,4 @@ else

-#	  define __EXTENSIONS__ 1
-	  $ac_includes_default
+#         define __EXTENSIONS__ 1
+          $ac_includes_default
 int
@@ -3614,3 +3749,3 @@ set dummy ${ac_tool_prefix}gcc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3626,3 +3761,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}gcc"
@@ -3654,3 +3789,3 @@ set dummy gcc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3666,3 +3801,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="gcc"
@@ -3707,3 +3842,3 @@ set dummy ${ac_tool_prefix}cc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3719,3 +3854,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="${ac_tool_prefix}cc"
@@ -3747,3 +3882,3 @@ set dummy cc; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3760,3 +3895,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then
@@ -3806,3 +3941,3 @@ set dummy $ac_tool_prefix$ac_prog; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_CC+set}" = set; then :
+if ${ac_cv_prog_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3818,3 +3953,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_CC="$ac_tool_prefix$ac_prog"
@@ -3850,3 +3985,3 @@ set dummy $ac_prog; ac_word=$2
 $as_echo_n "checking for $ac_word... " >&6; }
-if test "${ac_cv_prog_ac_ct_CC+set}" = set; then :
+if ${ac_cv_prog_ac_ct_CC+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3862,3 +3997,3 @@ do
     for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+  if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then
     ac_cv_prog_ac_ct_CC="$ac_prog"
@@ -3904,4 +4039,4 @@ test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd'
 $as_echo "$as_me: error: in \`$ac_pwd':" >&2;}
-as_fn_error "no acceptable C compiler found in \$PATH
-See \`config.log' for more details." "$LINENO" 5; }
+as_fn_error $? "no acceptable C compiler found in \$PATH
+See \`config.log' for more details" "$LINENO" 5; }

@@ -3926,4 +4061,4 @@ $as_echo "$ac_try_echo"; } >&5
     cat conftest.er1 >&5
-    rm -f conftest.er1 conftest.err
   fi
+  rm -f conftest.er1 conftest.err
   $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5
@@ -3934,3 +4069,3 @@ done
 $as_echo_n "checking whether we are using the GNU C compiler... " >&6; }
-if test "${ac_cv_c_compiler_gnu+set}" = set; then :
+if ${ac_cv_c_compiler_gnu+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -3971,3 +4106,3 @@ ac_save_CFLAGS=$CFLAGS
 $as_echo_n "checking whether $CC accepts -g... " >&6; }
-if test "${ac_cv_prog_cc_g+set}" = set; then :
+if ${ac_cv_prog_cc_g+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4049,3 +4184,3 @@ fi
 $as_echo_n "checking for $CC option to accept ISO C89... " >&6; }
-if test "${ac_cv_prog_cc_c89+set}" = set; then :
+if ${ac_cv_prog_cc_c89+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4058,4 +4193,3 @@ cat confdefs.h - <<_ACEOF >conftest.$ac_ext
 #include <stdio.h>
-#include <sys/types.h>
-#include <sys/stat.h>
+struct stat;
 /* Most of the following tests are stolen from RCS 5.7's src/conf.sh.  */
@@ -4147,3 +4281,3 @@ if test $ac_cv_c_compiler_gnu = yes; then
 $as_echo_n "checking whether $CC needs -traditional... " >&6; }
-if test "${ac_cv_prog_gcc_traditional+set}" = set; then :
+if ${ac_cv_prog_gcc_traditional+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4188,12 +4322,18 @@ ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
-  for ac_t in install-sh install.sh shtool; do
-    if test -f "$ac_dir/$ac_t"; then
-      ac_aux_dir=$ac_dir
-      ac_install_sh="$ac_aux_dir/$ac_t -c"
-      break 2
-    fi
-  done
+  if test -f "$ac_dir/install-sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install-sh -c"
+    break
+  elif test -f "$ac_dir/install.sh"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/install.sh -c"
+    break
+  elif test -f "$ac_dir/shtool"; then
+    ac_aux_dir=$ac_dir
+    ac_install_sh="$ac_aux_dir/shtool install -c"
+    break
+  fi
 done
 if test -z "$ac_aux_dir"; then
-  as_fn_error "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
+  as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5
 fi
@@ -4226,3 +4366,3 @@ $as_echo_n "checking for a BSD-compatible install... " >&6; }
 if test -z "$INSTALL"; then
-if test "${ac_cv_path_install+set}" = set; then :
+if ${ac_cv_path_install+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4246,3 +4386,3 @@ case $as_dir/ in #((
       for ac_exec_ext in '' $ac_executable_extensions; do
-	if { test -f "$as_dir/$ac_prog$ac_exec_ext" && $as_test_x "$as_dir/$ac_prog$ac_exec_ext"; }; then
+	if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then
 	  if test $ac_prog = install &&
@@ -4316,3 +4456,3 @@ echo "Using: BMAKE_PATH_MAX=$bmake_path_max" >&6
 $as_echo_n "checking for ANSI C header files... " >&6; }
-if test "${ac_cv_header_stdc+set}" = set; then :
+if ${ac_cv_header_stdc+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4428,3 +4568,3 @@ fi
 $as_echo_n "checking for sys/wait.h that is POSIX.1 compatible... " >&6; }
-if test "${ac_cv_header_sys_wait_h+set}" = set; then :
+if ${ac_cv_header_sys_wait_h+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4472,3 +4612,3 @@ for ac_hdr in dirent.h sys/ndir.h sys/dir.h ndir.h; do
 $as_echo_n "checking for $ac_hdr that defines DIR... " >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then :
+if eval \${$as_ac_Header+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4499,4 +4639,3 @@ eval ac_res=\$$as_ac_Header
 $as_echo "$ac_res" >&6; }
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
@@ -4513,3 +4652,3 @@ if test $ac_header_dirent = dirent.h; then
 $as_echo_n "checking for library containing opendir... " >&6; }
-if test "${ac_cv_search_opendir+set}" = set; then :
+if ${ac_cv_search_opendir+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4547,3 +4686,3 @@ rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if test "${ac_cv_search_opendir+set}" = set; then :
+  if ${ac_cv_search_opendir+:} false; then :
   break
@@ -4551,3 +4690,3 @@ fi
 done
-if test "${ac_cv_search_opendir+set}" = set; then :
+if ${ac_cv_search_opendir+:} false; then :

@@ -4570,3 +4709,3 @@ else
 $as_echo_n "checking for library containing opendir... " >&6; }
-if test "${ac_cv_search_opendir+set}" = set; then :
+if ${ac_cv_search_opendir+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4604,3 +4743,3 @@ rm -f core conftest.err conftest.$ac_objext \
     conftest$ac_exeext
-  if test "${ac_cv_search_opendir+set}" = set; then :
+  if ${ac_cv_search_opendir+:} false; then :
   break
@@ -4608,3 +4747,3 @@ fi
 done
-if test "${ac_cv_search_opendir+set}" = set; then :
+if ${ac_cv_search_opendir+:} false; then :

@@ -4629,3 +4768,3 @@ do :
   ac_fn_c_check_header_mongrel "$LINENO" "sys/param.h" "ac_cv_header_sys_param_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_param_h" = x""yes; then :
+if test "x$ac_cv_header_sys_param_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
@@ -4645,3 +4784,3 @@ do :
 "
-if test "x$ac_cv_header_sys_sysctl_h" = x""yes; then :
+if test "x$ac_cv_header_sys_sysctl_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
@@ -4666,2 +4805,3 @@ for ac_header in \
 	sys/mman.h \
+	sys/resource.h \
 	sys/select.h \
@@ -4670,2 +4810,4 @@ for ac_header in \
 	sys/uio.h \
+	sys/utsname.h \
+	sys/wait.h \
 	unistd.h \
@@ -4676,4 +4818,3 @@ do :
 ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default"
-eval as_val=\$$as_ac_Header
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_Header"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
@@ -4688,3 +4829,3 @@ done
 ac_fn_c_check_header_mongrel "$LINENO" "sys/cdefs.h" "ac_cv_header_sys_cdefs_h" "$ac_includes_default"
-if test "x$ac_cv_header_sys_cdefs_h" = x""yes; then :
+if test "x$ac_cv_header_sys_cdefs_h" = xyes; then :
   echo $ECHO_N "checking whether sys/cdefs.h is compatible... $ECHO_C" >&6
@@ -4715,3 +4856,3 @@ fi
 $as_echo_n "checking for __attribute__... " >&6; }
-if test "${ac_cv___attribute__+set}" = set; then :
+if ${ac_cv___attribute__+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4758,3 +4899,3 @@ $as_echo "$ac_cv___attribute__" >&6; }
 $as_echo_n "checking whether byte ordering is bigendian... " >&6; }
-if test "${ac_cv_c_bigendian+set}" = set; then :
+if ${ac_cv_c_bigendian+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4976,3 +5117,3 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
    *)
-     as_fn_error "unknown endianness
+     as_fn_error $? "unknown endianness
  presetting ac_cv_c_bigendian=no (or yes) will help" "$LINENO" 5 ;;
@@ -4982,3 +5123,3 @@ $as_echo "#define AC_APPLE_UNIVERSAL_BUILD 1" >>confdefs.h
 $as_echo_n "checking for an ANSI C-conforming const... " >&6; }
-if test "${ac_cv_c_const+set}" = set; then :
+if ${ac_cv_c_const+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -4991,7 +5132,7 @@ main ()
 {
-/* FIXME: Include the comments suggested by Paul. */
+
 #ifndef __cplusplus
-  /* Ultrix mips cc rejects this.  */
+  /* Ultrix mips cc rejects this sort of thing.  */
   typedef int charset[2];
-  const charset cs;
+  const charset cs = { 0, 0 };
   /* SunOS 4.1.1 cc rejects this.  */
@@ -5012,4 +5153,5 @@ main ()
   pcpcc = (char const *const *) ppc;
-  { /* SCO 3.2v4 cc rejects this.  */
-    char *t;
+  { /* SCO 3.2v4 cc rejects this sort of thing.  */
+    char tx;
+    char *t = &tx;
     char const *s = 0 ? (char *) 0 : (char const *) 0;
@@ -5029,6 +5171,6 @@ main ()
   }
-  { /* AIX XL C 1.02.0.0 rejects this saying
+  { /* AIX XL C 1.02.0.0 rejects this sort of thing, saying
        "k.c", line 2.27: 1506-025 (S) Operand must be a modifiable lvalue. */
-    struct s { int j; const int *ap[3]; };
-    struct s *b; b->j = 5;
+    struct s { int j; const int *ap[3]; } bx;
+    struct s *b = &bx; b->j = 5;
   }
@@ -5060,4 +5202,15 @@ fi

+ac_fn_c_find_intX_t "$LINENO" "32" "ac_cv_c_int32_t"
+case $ac_cv_c_int32_t in #(
+  no|yes) ;; #(
+  *)
+
+cat >>confdefs.h <<_ACEOF
+#define int32_t $ac_cv_c_int32_t
+_ACEOF
+;;
+esac
+
 ac_fn_c_check_type "$LINENO" "mode_t" "ac_cv_type_mode_t" "$ac_includes_default"
-if test "x$ac_cv_type_mode_t" = x""yes; then :
+if test "x$ac_cv_type_mode_t" = xyes; then :

@@ -5072,3 +5225,3 @@ fi
 ac_fn_c_check_type "$LINENO" "off_t" "ac_cv_type_off_t" "$ac_includes_default"
-if test "x$ac_cv_type_off_t" = x""yes; then :
+if test "x$ac_cv_type_off_t" = xyes; then :

@@ -5083,3 +5236,3 @@ fi
 ac_fn_c_check_type "$LINENO" "pid_t" "ac_cv_type_pid_t" "$ac_includes_default"
-if test "x$ac_cv_type_pid_t" = x""yes; then :
+if test "x$ac_cv_type_pid_t" = xyes; then :

@@ -5094,3 +5247,3 @@ fi
 ac_fn_c_check_type "$LINENO" "size_t" "ac_cv_type_size_t" "$ac_includes_default"
-if test "x$ac_cv_type_size_t" = x""yes; then :
+if test "x$ac_cv_type_size_t" = xyes; then :

@@ -5125,3 +5278,3 @@ ac_fn_c_check_decl "$LINENO" "sys_siglist" "ac_cv_have_decl_sys_siglist" "#inclu
 "
-if test "x$ac_cv_have_decl_sys_siglist" = x""yes; then :
+if test "x$ac_cv_have_decl_sys_siglist" = xyes; then :
   ac_have_decl=1
@@ -5138,3 +5291,3 @@ _ACEOF
 $as_echo_n "checking whether time.h and sys/time.h may both be included... " >&6; }
-if test "${ac_cv_header_time+set}" = set; then :
+if ${ac_cv_header_time+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5173,3 +5326,3 @@ fi
 $as_echo_n "checking whether struct tm is in sys/time.h or time.h... " >&6; }
-if test "${ac_cv_struct_tm+set}" = set; then :
+if ${ac_cv_struct_tm+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5209,3 +5362,3 @@ fi
 $as_echo_n "checking return type of signal handlers... " >&6; }
-if test "${ac_cv_type_signal+set}" = set; then :
+if ${ac_cv_type_signal+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5243,3 +5396,3 @@ do :
   ac_fn_c_check_header_mongrel "$LINENO" "vfork.h" "ac_cv_header_vfork_h" "$ac_includes_default"
-if test "x$ac_cv_header_vfork_h" = x""yes; then :
+if test "x$ac_cv_header_vfork_h" = xyes; then :
   cat >>confdefs.h <<_ACEOF
@@ -5256,4 +5409,3 @@ do :
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
@@ -5268,3 +5420,3 @@ if test "x$ac_cv_func_fork" = xyes; then
 $as_echo_n "checking for working fork... " >&6; }
-if test "${ac_cv_func_fork_works+set}" = set; then :
+if ${ac_cv_func_fork_works+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5321,3 +5473,3 @@ if test "x$ac_cv_func_vfork" = xyes; then
 $as_echo_n "checking for working vfork... " >&6; }
-if test "${ac_cv_func_vfork_works+set}" = set; then :
+if ${ac_cv_func_vfork_works+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5457,3 +5609,3 @@ do :
   ac_fn_c_check_func "$LINENO" "vprintf" "ac_cv_func_vprintf"
-if test "x$ac_cv_func_vprintf" = x""yes; then :
+if test "x$ac_cv_func_vprintf" = xyes; then :
   cat >>confdefs.h <<_ACEOF
@@ -5463,3 +5615,3 @@ _ACEOF
 ac_fn_c_check_func "$LINENO" "_doprnt" "ac_cv_func__doprnt"
-if test "x$ac_cv_func__doprnt" = x""yes; then :
+if test "x$ac_cv_func__doprnt" = xyes; then :

@@ -5475,3 +5627,3 @@ done
 $as_echo_n "checking for wait3 that fills in rusage... " >&6; }
-if test "${ac_cv_func_wait3_rusage+set}" = set; then :
+if ${ac_cv_func_wait3_rusage+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5538,18 +5690,109 @@ fi
 for ac_func in \
+    _Exit \
+    alloca \
+    atoll \
+    canonicalize_file_name \
+    chown \
+    dup2 \
+    dup3 \
+    endusershell \
 	err \
 	errx \
+	euidaccess \
+	faccessat \
+	fchdir \
+	fchmodat \
+	fchownat \
+	fcntl \
+	fdatasync \
+	fstatat \
+	fsync \
+	ftruncate \
+	futimens \
 	getcwd \
+	getdomainname \
+	getdtablesize \
 	getenv \
+	getgroups \
+	gethostname \
+	getloadavg \
+	getlogin \
+	getlogin_r \
 	getopt \
+	getpass \
+	getppid \
+	getrusage \
+	getsubopt \
+	getusershell \
 	getwd \
+	grantpt \
+	group_member \
+	initstate \
+	initstate_r \
+	kill \
 	killpg \
+	lchmod \
+	lchown \
+	link \
+	linkat \
+	lstat \
+	mkdirat \
+	mkdtemp \
+	mkfifo \
+	mkfifoat \
+	mknod \
+	mknodat \
+	mkostemp \
+	mkostemps \
+	mkstemp \
+	mkstemps \
 	mmap \
+	openat \
+	pipe \
+	pipe2 \
+	poll \
+	posix_openpt \
+	pread \
+	pthread_sigmask \
+	ptsname \
+	ptsname_r \
 	putenv \
+	pwrite \
+	qsort_r \
+	raise \
+	random \
+	random_r \
+	readlink \
+	readlinkat \
+	reallocarray \
+	realpath \
+    regcomp \
+    regerror \
+    regexec \
+    regfree \
+	rpmatch \
+	secure_getenv \
 	select \
 	setenv \
+	sethostname \
 	setpgid \
+	setpgrp \
 	setsid \
+	setstate \
+    setstate_r \
+    setusershell \
 	sigaction \
+	sigaddset \
+	sigdelset \
+	sigemptyset \
+	sigfillset \
+	sigismember \
+	signal \
+	sigpending \
+	sigprocmask \
 	sigvec \
+	sleep \
 	snprintf \
+	srandom \
+	srandom_r \
 	strerror \
@@ -5559,5 +5802,17 @@ for ac_func in \
 	strtol \
+	strtoll \
+	strtoull \
+	symlink \
+	symlinkat \
 	sysctl \
+	truncate \
+	ttyname_r \
+	uname \
+	unlinkat \
+	unlockpt \
 	unsetenv \
+	usleep \
+	utimensat \
 	vsnprintf \
+	wait \
 	wait3 \
@@ -5571,4 +5826,3 @@ do :
 ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
+if eval test \"x\$"$as_ac_var"\" = x"yes"; then :
   cat >>confdefs.h <<_ACEOF
@@ -5581,16 +5835,18 @@ done

-for ac_func in \
-	realpath \
-	dirname \
-	stresep \
-	strlcpy \
+ac_fn_c_check_func "$LINENO" "realpath" "ac_cv_func_realpath"
+if test "x$ac_cv_func_realpath" = xyes; then :
+  $as_echo "#define HAVE_REALPATH 1" >>confdefs.h

-do :
-  as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh`
-ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var"
-eval as_val=\$$as_ac_var
-   if test "x$as_val" = x""yes; then :
-  cat >>confdefs.h <<_ACEOF
-#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+else
+  case " $LIBOBJS " in
+  *" realpath.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS realpath.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "dirname" "ac_cv_func_dirname"
+if test "x$ac_cv_func_dirname" = xyes; then :
+  $as_echo "#define HAVE_DIRNAME 1" >>confdefs.h

@@ -5598,4 +5854,30 @@ else
   case " $LIBOBJS " in
-  *" $ac_func.$ac_objext "* ) ;;
-  *) LIBOBJS="$LIBOBJS $ac_func.$ac_objext"
+  *" dirname.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS dirname.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "stresep" "ac_cv_func_stresep"
+if test "x$ac_cv_func_stresep" = xyes; then :
+  $as_echo "#define HAVE_STRESEP 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" stresep.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS stresep.$ac_objext"
+ ;;
+esac
+
+fi
+
+ac_fn_c_check_func "$LINENO" "strlcpy" "ac_cv_func_strlcpy"
+if test "x$ac_cv_func_strlcpy" = xyes; then :
+  $as_echo "#define HAVE_STRLCPY 1" >>confdefs.h
+
+else
+  case " $LIBOBJS " in
+  *" strlcpy.$ac_objext "* ) ;;
+  *) LIBOBJS="$LIBOBJS strlcpy.$ac_objext"
  ;;
@@ -5604,3 +5886,2 @@ esac
 fi
-done

@@ -5610,3 +5891,3 @@ done
 $as_echo_n "checking for emalloc in -lutil... " >&6; }
-if test "${ac_cv_lib_util_emalloc+set}" = set; then :
+if ${ac_cv_lib_util_emalloc+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5644,6 +5925,6 @@ fi
 $as_echo "$ac_cv_lib_util_emalloc" >&6; }
-if test "x$ac_cv_lib_util_emalloc" = x""yes; then :
+if test "x$ac_cv_lib_util_emalloc" = xyes; then :
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for erealloc in -lutil" >&5
 $as_echo_n "checking for erealloc in -lutil... " >&6; }
-if test "${ac_cv_lib_util_erealloc+set}" = set; then :
+if ${ac_cv_lib_util_erealloc+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5681,6 +5962,6 @@ fi
 $as_echo "$ac_cv_lib_util_erealloc" >&6; }
-if test "x$ac_cv_lib_util_erealloc" = x""yes; then :
+if test "x$ac_cv_lib_util_erealloc" = xyes; then :
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for estrdup in -lutil" >&5
 $as_echo_n "checking for estrdup in -lutil... " >&6; }
-if test "${ac_cv_lib_util_estrdup+set}" = set; then :
+if ${ac_cv_lib_util_estrdup+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5718,6 +5999,6 @@ fi
 $as_echo "$ac_cv_lib_util_estrdup" >&6; }
-if test "x$ac_cv_lib_util_estrdup" = x""yes; then :
+if test "x$ac_cv_lib_util_estrdup" = xyes; then :
    { $as_echo "$as_me:${as_lineno-$LINENO}: checking for estrndup in -lutil" >&5
 $as_echo_n "checking for estrndup in -lutil... " >&6; }
-if test "${ac_cv_lib_util_estrndup+set}" = set; then :
+if ${ac_cv_lib_util_estrndup+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5755,3 +6036,3 @@ fi
 $as_echo "$ac_cv_lib_util_estrndup" >&6; }
-if test "x$ac_cv_lib_util_estrndup" = x""yes; then :
+if test "x$ac_cv_lib_util_estrndup" = xyes; then :
    LIBS="$LIBS -lutil"
@@ -5769,3 +6050,3 @@ fi
 $as_echo_n "checking whether stat file-mode macros are broken... " >&6; }
-if test "${ac_cv_header_stat_broken+set}" = set; then :
+if ${ac_cv_header_stat_broken+:} false; then :
   $as_echo_n "(cached) " >&6
@@ -5810,3 +6091,3 @@ fi
 ac_fn_c_check_member "$LINENO" "struct stat" "st_rdev" "ac_cv_member_struct_stat_st_rdev" "$ac_includes_default"
-if test "x$ac_cv_member_struct_stat_st_rdev" = x""yes; then :
+if test "x$ac_cv_member_struct_stat_st_rdev" = xyes; then :

@@ -5881,3 +6162,3 @@ if test "${with_machine+set}" = set; then :
   withval=$with_machine; case "${withval}" in
-yes)   as_fn_error "bad value ${withval} given for bmake MACHINE" "$LINENO" 5 ;;
+yes)   as_fn_error $? "bad value ${withval} given for bmake MACHINE" "$LINENO" 5 ;;
 no)    ;;
@@ -5914,3 +6195,3 @@ if test "${with_machine_arch+set}" = set; then :
   withval=$with_machine_arch; case "${withval}" in
-yes)   as_fn_error "bad value ${withval} given for bmake MACHINE_ARCH" "$LINENO" 5 ;;
+yes)   as_fn_error $? "bad value ${withval} given for bmake MACHINE_ARCH" "$LINENO" 5 ;;
 no)    ;;
@@ -5926,3 +6207,3 @@ if test "${with_default_sys_path+set}" = set; then :
   withval=$with_default_sys_path; case "${withval}" in
-yes)	as_fn_error "bad value ${withval} given for bmake _PATH_DEFSYSPATH" "$LINENO" 5 ;;
+yes)	as_fn_error $? "bad value ${withval} given for bmake _PATH_DEFSYSPATH" "$LINENO" 5 ;;
 no)	;;
@@ -5937,3 +6218,3 @@ if test "${with_path_objdirprefix+set}" = set; then :
   withval=$with_path_objdirprefix; case "${withval}" in
-yes)   as_fn_error "bad value ${withval} given for bmake _PATH_OBJDIRPREFIX" "$LINENO" 5 ;;
+yes)   as_fn_error $? "bad value ${withval} given for bmake _PATH_OBJDIRPREFIX" "$LINENO" 5 ;;
 no)    CPPFLAGS="$CPPFLAGS -DNO_PATH_OBJDIRPREFIX" ;;
@@ -5948,3 +6229,3 @@ yes)   ;;
 no)    CPPFLAGS="$CPPFLAGS -DNO_PWD_OVERRIDE" ;;
-*)     as_fn_error "bad value ${enableval} given for pwd-override option" "$LINENO" 5 ;;
+*)     as_fn_error $? "bad value ${enableval} given for pwd-override option" "$LINENO" 5 ;;
 esac
@@ -5957,3 +6238,3 @@ yes)   ;;
 no)    CPPFLAGS="$CPPFLAGS -DNO_CHECK_MAKE_CHDIR" ;;
-*)     as_fn_error "bad value ${enableval} given for check-make-chdir option" "$LINENO" 5 ;;
+*)     as_fn_error $? "bad value ${enableval} given for check-make-chdir option" "$LINENO" 5 ;;
 esac
@@ -5967,3 +6248,3 @@ if test "${with_mksrc+set}" = set; then :
 *) test -s $withval/install-mk && mksrc=$withval ||
-as_fn_error "bad value ${withval} given for mksrc cannot find install-mk" "$LINENO" 5
+as_fn_error $? "bad value ${withval} given for mksrc cannot find install-mk" "$LINENO" 5
 ;;
@@ -6011,3 +6292,3 @@ fi

-ac_config_files="$ac_config_files makefile Makefile.config make-bootstrap.sh unit-tests/Makefile"
+ac_config_files="$ac_config_files Makefile.config make-bootstrap.sh unit-tests/Makefile"

@@ -6077,6 +6358,17 @@ if diff "$cache_file" confcache >/dev/null 2>&1; then :; else
   if test -w "$cache_file"; then
-    test "x$cache_file" != "x/dev/null" &&
+    if test "x$cache_file" != "x/dev/null"; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5
 $as_echo "$as_me: updating cache $cache_file" >&6;}
-    cat confcache >$cache_file
+      if test ! -f "$cache_file" || test -h "$cache_file"; then
+	cat confcache >"$cache_file"
+      else
+        case $cache_file in #(
+        */* | ?:*)
+	  mv -f confcache "$cache_file"$$ &&
+	  mv -f "$cache_file"$$ "$cache_file" ;; #(
+        *)
+	  mv -f confcache "$cache_file" ;;
+	esac
+      fi
+    fi
   else
@@ -6096,2 +6388,3 @@ ac_libobjs=
 ac_ltlibobjs=
+U=
 for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue
@@ -6112,3 +6405,3 @@ LTLIBOBJS=$ac_ltlibobjs

-: ${CONFIG_STATUS=./config.status}
+: "${CONFIG_STATUS=./config.status}"
 ac_write_fail=0
@@ -6213,2 +6506,3 @@ IFS=" ""	$as_nl"
 # Find who we are.  Look in the path if we contain no directory separator.
+as_myself=
 case $0 in #((
@@ -6258,15 +6552,15 @@ export LANGUAGE

-# as_fn_error ERROR [LINENO LOG_FD]
-# ---------------------------------
+# as_fn_error STATUS ERROR [LINENO LOG_FD]
+# ----------------------------------------
 # Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are
 # provided, also output the error to LOG_FD, referencing LINENO. Then exit the
-# script with status $?, using 1 if that was 0.
+# script with STATUS, using 1 if that was 0.
 as_fn_error ()
 {
-  as_status=$?; test $as_status -eq 0 && as_status=1
-  if test "$3"; then
-    as_lineno=${as_lineno-"$2"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
-    $as_echo "$as_me:${as_lineno-$LINENO}: error: $1" >&$3
+  as_status=$1; test $as_status -eq 0 && as_status=1
+  if test "$4"; then
+    as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack
+    $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4
   fi
-  $as_echo "$as_me: error: $1" >&2
+  $as_echo "$as_me: error: $2" >&2
   as_fn_exit $as_status
@@ -6408,5 +6702,5 @@ if (echo >conf$$.file) 2>/dev/null; then
     # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable.
-    # In both cases, we have to default to `cp -p'.
+    # In both cases, we have to default to `cp -pR'.
     ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe ||
-      as_ln_s='cp -p'
+      as_ln_s='cp -pR'
   elif ln conf$$.file conf$$ 2>/dev/null; then
@@ -6414,6 +6708,6 @@ if (echo >conf$$.file) 2>/dev/null; then
   else
-    as_ln_s='cp -p'
+    as_ln_s='cp -pR'
   fi
 else
-  as_ln_s='cp -p'
+  as_ln_s='cp -pR'
 fi
@@ -6466,3 +6760,3 @@ $as_echo X"$as_dir" |
     test -z "$as_dirs" || eval "mkdir $as_dirs"
-  } || test -d "$as_dir" || as_fn_error "cannot create directory $as_dir"
+  } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir"

@@ -6477,24 +6771,12 @@ fi

-if test -x / >/dev/null 2>&1; then
-  as_test_x='test -x'
-else
-  if ls -dL / >/dev/null 2>&1; then
-    as_ls_L_option=L
-  else
-    as_ls_L_option=
-  fi
-  as_test_x='
-    eval sh -c '\''
-      if test -d "$1"; then
-	test -d "$1/.";
-      else
-	case $1 in #(
-	-*)set "./$1";;
-	esac;
-	case `ls -ld'$as_ls_L_option' "$1" 2>/dev/null` in #((
-	???[sx]*):;;*)false;;esac;fi
-    '\'' sh
-  '
-fi
-as_executable_p=$as_test_x
+
+# as_fn_executable_p FILE
+# -----------------------
+# Test if FILE is an executable regular file.
+as_fn_executable_p ()
+{
+  test -f "$1" && test -x "$1"
+} # as_fn_executable_p
+as_test_x='test -x'
+as_executable_p=as_fn_executable_p

@@ -6520,3 +6802,3 @@ ac_log="
 This file was extended by bmake $as_me 20171126, which was
-generated by GNU Autoconf 2.64.  Invocation command line was
+generated by GNU Autoconf 2.69.  Invocation command line was

@@ -6559,2 +6841,3 @@ Usage: $0 [OPTION]... [TAG]...
   -V, --version    print version number and configuration settings, then exit
+      --config     print configuration, then exit
   -q, --quiet, --silent
@@ -6578,8 +6861,9 @@ _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
+ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
 ac_cs_version="\\
 bmake config.status 20171126
-configured by $0, generated by GNU Autoconf 2.64,
-  with options \\"`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
+configured by $0, generated by GNU Autoconf 2.69,
+  with options \\"\$ac_cs_config\\"

-Copyright (C) 2009 Free Software Foundation, Inc.
+Copyright (C) 2012 Free Software Foundation, Inc.
 This config.status script is free software; the Free Software Foundation
@@ -6599,3 +6883,3 @@ do
   case $1 in
-  --*=*)
+  --*=?*)
     ac_option=`expr "X$1" : 'X\([^=]*\)='`
@@ -6604,2 +6888,7 @@ do
     ;;
+  --*=)
+    ac_option=`expr "X$1" : 'X\([^=]*\)='`
+    ac_optarg=
+    ac_shift=:
+    ;;
   *)
@@ -6617,2 +6906,4 @@ do
     $as_echo "$ac_cs_version"; exit ;;
+  --config | --confi | --conf | --con | --co | --c )
+    $as_echo "$ac_cs_config"; exit ;;
   --debug | --debu | --deb | --de | --d | -d )
@@ -6623,2 +6914,3 @@ do
     *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;;
+    '') as_fn_error $? "missing file argument" ;;
     esac
@@ -6635,3 +6927,3 @@ do
     # Conflict between --help and --header
-    as_fn_error "ambiguous option: \`$1'
+    as_fn_error $? "ambiguous option: \`$1'
 Try \`$0 --help' for more information.";;
@@ -6644,3 +6936,3 @@ Try \`$0 --help' for more information.";;
   # This is an error.
-  -*) as_fn_error "unrecognized option: \`$1'
+  -*) as_fn_error $? "unrecognized option: \`$1'
 Try \`$0 --help' for more information." ;;
@@ -6664,3 +6956,3 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 if \$ac_cs_recheck; then
-  set X '$SHELL' '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
+  set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion
   shift
@@ -6694,3 +6986,2 @@ do
     "config.h") CONFIG_HEADERS="$CONFIG_HEADERS config.h" ;;
-    "makefile") CONFIG_FILES="$CONFIG_FILES makefile" ;;
     "Makefile.config") CONFIG_FILES="$CONFIG_FILES Makefile.config" ;;
@@ -6699,3 +6990,3 @@ do

-  *) as_fn_error "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
+  *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;;
   esac
@@ -6721,5 +7012,6 @@ $debug ||
 {
-  tmp=
+  tmp= ac_tmp=
   trap 'exit_status=$?
-  { test -z "$tmp" || test ! -d "$tmp" || rm -fr "$tmp"; } && exit $exit_status
+  : "${ac_tmp:=$tmp}"
+  { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status
 ' 0
@@ -6731,3 +7023,3 @@ $debug ||
   tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` &&
-  test -n "$tmp" && test -d "$tmp"
+  test -d "$tmp"
 }  ||
@@ -6736,3 +7028,4 @@ $debug ||
   (umask 077 && mkdir "$tmp")
-} || as_fn_error "cannot create a temporary directory in ." "$LINENO" 5
+} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5
+ac_tmp=$tmp

@@ -6753,3 +7046,3 @@ ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' </dev/null 2>/dev/null`
 if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then
-  ac_cs_awk_cr='\r'
+  ac_cs_awk_cr='\\r'
 else
@@ -6758,3 +7051,3 @@ fi

-echo 'BEGIN {' >"$tmp/subs1.awk" &&
+echo 'BEGIN {' >"$ac_tmp/subs1.awk" &&
 _ACEOF
@@ -6767,4 +7060,4 @@ _ACEOF
 } >conf$$subs.sh ||
-  as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
-ac_delim_num=`echo "$ac_subst_vars" | grep -c '$'`
+  as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
+ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'`
 ac_delim='%!_!# '
@@ -6772,3 +7065,3 @@ for ac_last_try in false false false false false :; do
   . ./conf$$subs.sh ||
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5

@@ -6778,3 +7071,3 @@ for ac_last_try in false false false false false :; do
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_STATUS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5
   else
@@ -6786,3 +7079,3 @@ rm -f conf$$subs.sh
 cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
-cat >>"\$tmp/subs1.awk" <<\\_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK &&
 _ACEOF
@@ -6800,3 +7093,3 @@ t delim
 h
-s/\(.\{148\}\).*/\1/
+s/\(.\{148\}\)..*/\1/
 t more1
@@ -6814,3 +7107,3 @@ t nl
 h
-s/\(.\{148\}\).*/\1/
+s/\(.\{148\}\)..*/\1/
 t more2
@@ -6834,3 +7127,3 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
 _ACAWK
-cat >>"\$tmp/subs1.awk" <<_ACAWK &&
+cat >>"\$ac_tmp/subs1.awk" <<_ACAWK &&
   for (key in S) S_is_set[key] = 1
@@ -6866,8 +7159,8 @@ else
   cat
-fi < "$tmp/subs1.awk" > "$tmp/subs.awk" \
-  || as_fn_error "could not setup config files machinery" "$LINENO" 5
+fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \
+  || as_fn_error $? "could not setup config files machinery" "$LINENO" 5
 _ACEOF

-# VPATH may cause trouble with some makes, so we remove $(srcdir),
-# ${srcdir} and @srcdir@ from VPATH if srcdir is ".", strip leading and
+# VPATH may cause trouble with some makes, so we remove sole $(srcdir),
+# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and
 # trailing colons and then remove the whole line if VPATH becomes empty
@@ -6875,8 +7168,16 @@ _ACEOF
 if test "x$srcdir" = x.; then
-  ac_vpsub='/^[	 ]*VPATH[	 ]*=/{
-s/:*\$(srcdir):*/:/
-s/:*\${srcdir}:*/:/
-s/:*@srcdir@:*/:/
-s/^\([^=]*=[	 ]*\):*/\1/
+  ac_vpsub='/^[	 ]*VPATH[	 ]*=[	 ]*/{
+h
+s///
+s/^/:/
+s/[	 ]*$/:/
+s/:\$(srcdir):/:/g
+s/:\${srcdir}:/:/g
+s/:@srcdir@:/:/g
+s/^:*//
 s/:*$//
+x
+s/\(=[	 ]*\).*/\1/
+G
+s/\n//
 s/^[^=]*=[	 ]*$//
@@ -6892,3 +7193,3 @@ fi # test -n "$CONFIG_FILES"
 if test -n "$CONFIG_HEADERS"; then
-cat >"$tmp/defines.awk" <<\_ACAWK ||
+cat >"$ac_tmp/defines.awk" <<\_ACAWK ||
 BEGIN {
@@ -6904,7 +7205,7 @@ ac_delim='%!_!# '
 for ac_last_try in false false :; do
-  ac_t=`sed -n "/$ac_delim/p" confdefs.h`
-  if test -z "$ac_t"; then
+  ac_tt=`sed -n "/$ac_delim/p" confdefs.h`
+  if test -z "$ac_tt"; then
     break
   elif $ac_last_try; then
-    as_fn_error "could not make $CONFIG_HEADERS" "$LINENO" 5
+    as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5
   else
@@ -6993,3 +7294,3 @@ _ACEOF
 cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
-  as_fn_error "could not setup config headers machinery" "$LINENO" 5
+  as_fn_error $? "could not setup config headers machinery" "$LINENO" 5
 fi # test -n "$CONFIG_HEADERS"
@@ -7006,3 +7307,3 @@ do
   :[FHL]*:*);;
-  :L* | :C*:*) as_fn_error "invalid tag \`$ac_tag'" "$LINENO" 5;;
+  :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;;
   :[FH]-) ac_tag=-:-;;
@@ -7025,3 +7326,3 @@ do
       case $ac_f in
-      -) ac_f="$tmp/stdin";;
+      -) ac_f="$ac_tmp/stdin";;
       *) # Look for the file first in the build tree, then in the source tree
@@ -7034,3 +7335,3 @@ do
 	   esac ||
-	   as_fn_error "cannot find input file: \`$ac_f'" "$LINENO" 5;;
+	   as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;;
       esac
@@ -7060,4 +7361,4 @@ $as_echo "$as_me: creating $ac_file" >&6;}
     case $ac_tag in
-    *:-:* | *:-) cat >"$tmp/stdin" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5 ;;
+    *:-:* | *:-) cat >"$ac_tmp/stdin" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;;
     esac
@@ -7191,19 +7492,20 @@ $ac_datarootdir_hack
 "
-eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$tmp/subs.awk" >$tmp/out \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \
+  >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5

 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
-  { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
-  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' "$tmp/out"`; test -z "$ac_out"; } &&
+  { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } &&
+  { ac_out=`sed -n '/^[	 ]*datarootdir[	 ]*:*=/p' \
+      "$ac_tmp/out"`; test -z "$ac_out"; } &&
   { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&5
+which seems to be undefined.  Please make sure it is defined" >&5
 $as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir'
-which seems to be undefined.  Please make sure it is defined." >&2;}
+which seems to be undefined.  Please make sure it is defined" >&2;}

-  rm -f "$tmp/stdin"
+  rm -f "$ac_tmp/stdin"
   case $ac_file in
-  -) cat "$tmp/out" && rm -f "$tmp/out";;
-  *) rm -f "$ac_file" && mv "$tmp/out" "$ac_file";;
+  -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";;
+  *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";;
   esac \
-  || as_fn_error "could not create $ac_file" "$LINENO" 5
+  || as_fn_error $? "could not create $ac_file" "$LINENO" 5
  ;;
@@ -7216,6 +7518,6 @@ which seems to be undefined.  Please make sure it is defined." >&2;}
       $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs"
-    } >"$tmp/config.h" \
-      || as_fn_error "could not create $ac_file" "$LINENO" 5
-    if diff "$ac_file" "$tmp/config.h" >/dev/null 2>&1; then
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs"
+    } >"$ac_tmp/config.h" \
+      || as_fn_error $? "could not create $ac_file" "$LINENO" 5
+    if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then
       { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5
@@ -7224,4 +7526,4 @@ $as_echo "$as_me: $ac_file is unchanged" >&6;}
       rm -f "$ac_file"
-      mv "$tmp/config.h" "$ac_file" \
-	|| as_fn_error "could not create $ac_file" "$LINENO" 5
+      mv "$ac_tmp/config.h" "$ac_file" \
+	|| as_fn_error $? "could not create $ac_file" "$LINENO" 5
     fi
@@ -7229,4 +7531,4 @@ $as_echo "$as_me: $ac_file is unchanged" >&6;}
     $as_echo "/* $configure_input  */" \
-      && eval '$AWK -f "$tmp/defines.awk"' "$ac_file_inputs" \
-      || as_fn_error "could not create -" "$LINENO" 5
+      && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \
+      || as_fn_error $? "could not create -" "$LINENO" 5
   fi
@@ -7245,3 +7547,3 @@ ac_clean_files=$ac_clean_files_save
 test $ac_write_fail = 0 ||
-  as_fn_error "write failure creating $CONFIG_STATUS" "$LINENO" 5
+  as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5

@@ -7266,3 +7568,3 @@ if test "$no_create" != yes; then
   # would make configure fail if this is the last instruction.
-  $ac_cs_success || as_fn_exit $?
+  $ac_cs_success || as_fn_exit 1
 fi
diff --git a/configure.in b/configure.in
index ccd4262..81231ca 100644
--- a/configure.in
+++ b/configure.in
@@ -50,3 +50,3 @@ esac],
 [
-OS=`uname -s`
+OS=`uname -s | cut -d_ -f1`
 for d in "/usr/include/dev/filemon" "$prefix/include/dev/filemon" "$srcdir/filemon" "$srcdir/../filemon" "$srcdir/../../sys/dev/filemon"
@@ -125,2 +125,3 @@ AC_CHECK_HEADERS( \
 	sys/mman.h \
+	sys/resource.h \
 	sys/select.h \
@@ -129,2 +130,4 @@ AC_CHECK_HEADERS( \
 	sys/uio.h \
+	sys/utsname.h \
+	sys/wait.h \
 	unistd.h \
@@ -153,2 +156,3 @@ AC_C_BIGENDIAN
 AC_C_CONST
+AC_TYPE_INT32_T
 AC_TYPE_MODE_T
@@ -169,18 +173,109 @@ dnl Keep this list sorted
 AC_CHECK_FUNCS( \
+    _Exit \
+    alloca \
+    atoll \
+    canonicalize_file_name \
+    chown \
+    dup2 \
+    dup3 \
+    endusershell \
 	err \
 	errx \
+	euidaccess \
+	faccessat \
+	fchdir \
+	fchmodat \
+	fchownat \
+	fcntl \
+	fdatasync \
+	fstatat \
+	fsync \
+	ftruncate \
+	futimens \
 	getcwd \
+	getdomainname \
+	getdtablesize \
 	getenv \
+	getgroups \
+	gethostname \
+	getloadavg \
+	getlogin \
+	getlogin_r \
 	getopt \
+	getpass \
+	getppid \
+	getrusage \
+	getsubopt \
+	getusershell \
 	getwd \
+	grantpt \
+	group_member \
+	initstate \
+	initstate_r \
+	kill \
 	killpg \
+	lchmod \
+	lchown \
+	link \
+	linkat \
+	lstat \
+	mkdirat \
+	mkdtemp \
+	mkfifo \
+	mkfifoat \
+	mknod \
+	mknodat \
+	mkostemp \
+	mkostemps \
+	mkstemp \
+	mkstemps \
 	mmap \
+	openat \
+	pipe \
+	pipe2 \
+	poll \
+	posix_openpt \
+	pread \
+	pthread_sigmask \
+	ptsname \
+	ptsname_r \
 	putenv \
+	pwrite \
+	qsort_r \
+	raise \
+	random \
+	random_r \
+	readlink \
+	readlinkat \
+	reallocarray \
+	realpath \
+    regcomp \
+    regerror \
+    regexec \
+    regfree \
+	rpmatch \
+	secure_getenv \
 	select \
 	setenv \
+	sethostname \
 	setpgid \
+	setpgrp \
 	setsid \
+	setstate \
+    setstate_r \
+    setusershell \
 	sigaction \
+	sigaddset \
+	sigdelset \
+	sigemptyset \
+	sigfillset \
+	sigismember \
+	signal \
+	sigpending \
+	sigprocmask \
 	sigvec \
+	sleep \
 	snprintf \
+	srandom \
+	srandom_r \
 	strerror \
@@ -190,5 +285,17 @@ AC_CHECK_FUNCS( \
 	strtol \
+	strtoll \
+	strtoull \
+	symlink \
+	symlinkat \
 	sysctl \
+	truncate \
+	ttyname_r \
+	uname \
+	unlinkat \
+	unlockpt \
 	unsetenv \
+	usleep \
+	utimensat \
 	vsnprintf \
+	wait \
 	wait3 \
@@ -392,3 +499,3 @@ AC_SUBST(filemon_h)
 AC_SUBST(_MAKE_VERSION)
-AC_OUTPUT(makefile Makefile.config make-bootstrap.sh unit-tests/Makefile)
+AC_OUTPUT(Makefile.config make-bootstrap.sh unit-tests/Makefile)

diff --git a/dir.c b/dir.c
index 0062ac0..8ff040b 100644
--- a/dir.c
+++ b/dir.c
@@ -139,2 +139,5 @@ __RCSID("$NetBSD: dir.c,v 1.73 2018/07/12 18:03:31 christos Exp $");
 #include <sys/stat.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif

diff --git a/headers-mingw/fcntl.h b/headers-mingw/fcntl.h
new file mode 100644
index 0000000..b63a9d3
--- /dev/null
+++ b/headers-mingw/fcntl.h
@@ -0,0 +1,244 @@
+/* Like <fcntl.h>, but with non-working flags defined to 0.
+
+   Copyright (C) 2006-2018 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* written by Paul Eggert */
+
+/* Normal invocation convention.  */
+
+#ifndef _GL_FCNTL_H
+#define _GL_FCNTL_H
+
+#ifndef __GLIBC__ /* Avoid namespace pollution on glibc systems.  */
+# include <unistd.h>
+#endif
+
+/* Native Windows platforms declare open(), creat() in <io.h>.  */
+#if (defined _WIN32 && ! defined __CYGWIN__)
+# include <io.h>
+#endif
+
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Declare overridden functions.  */
+
+
+
+#if !HAVE_FCNTL
+extern int fcntl (int fd, int action, ...);
+#endif
+
+#if !HAVE_OPENAT
+extern int openat (int fd, char const *file, int flags, /* mode_t mode */ ...);
+#  endif
+
+
+
+/* Fix up the FD_* macros, only known to be missing on mingw.  */
+
+#ifndef FD_CLOEXEC
+# define FD_CLOEXEC 1
+#endif
+
+/* Fix up the supported F_* macros.  Intentionally leave other F_*
+   macros undefined.  Only known to be missing on mingw.  */
+
+#ifndef F_DUPFD_CLOEXEC
+# define F_DUPFD_CLOEXEC 0x40000000
+/* Witness variable: 1 if gnulib defined F_DUPFD_CLOEXEC, 0 otherwise.  */
+# define GNULIB_defined_F_DUPFD_CLOEXEC 1
+#else
+# define GNULIB_defined_F_DUPFD_CLOEXEC 0
+#endif
+
+#ifndef F_DUPFD
+# define F_DUPFD 1
+#endif
+
+#ifndef F_GETFD
+# define F_GETFD 2
+#endif
+
+/* Fix up the O_* macros.  */
+
+#if !defined O_DIRECT && defined O_DIRECTIO
+/* Tru64 spells it 'O_DIRECTIO'.  */
+# define O_DIRECT O_DIRECTIO
+#endif
+
+#if !defined O_CLOEXEC && defined O_NOINHERIT
+/* Mingw spells it 'O_NOINHERIT'.  */
+# define O_CLOEXEC O_NOINHERIT
+#endif
+
+#ifndef O_CLOEXEC
+# define O_CLOEXEC 0x40000000 /* Try to not collide with system O_* flags.  */
+# define GNULIB_defined_O_CLOEXEC 1
+#else
+# define GNULIB_defined_O_CLOEXEC 0
+#endif
+
+#ifndef O_DIRECT
+# define O_DIRECT 0
+#endif
+
+#ifndef O_DIRECTORY
+# define O_DIRECTORY 0
+#endif
+
+#ifndef O_DSYNC
+# define O_DSYNC 0
+#endif
+
+#ifndef O_EXEC
+# define O_EXEC O_RDONLY /* This is often close enough in older systems.  */
+#endif
+
+#ifndef O_IGNORE_CTTY
+# define O_IGNORE_CTTY 0
+#endif
+
+#ifndef O_NDELAY
+# define O_NDELAY 0
+#endif
+
+#ifndef O_NOATIME
+# define O_NOATIME 0
+#endif
+
+#ifndef O_NONBLOCK
+# define O_NONBLOCK O_NDELAY
+#endif
+
+///* If the gnulib module 'nonblocking' is in use, guarantee a working non-zero
+//   value of O_NONBLOCK.  Otherwise, O_NONBLOCK is defined (above) to O_NDELAY
+//   or to 0 as fallback.  */
+//#if @GNULIB_NONBLOCKING@
+//# if O_NONBLOCK
+//#  define GNULIB_defined_O_NONBLOCK 0
+//# else
+//#  define GNULIB_defined_O_NONBLOCK 1
+//#  undef O_NONBLOCK
+//#  define O_NONBLOCK 0x40000000
+//# endif
+//#endif
+
+#ifndef O_NOCTTY
+# define O_NOCTTY 0
+#endif
+
+#ifndef O_NOFOLLOW
+# define O_NOFOLLOW 0
+#endif
+
+#ifndef O_NOLINK
+# define O_NOLINK 0
+#endif
+
+#ifndef O_NOLINKS
+# define O_NOLINKS 0
+#endif
+
+#ifndef O_NOTRANS
+# define O_NOTRANS 0
+#endif
+
+#ifndef O_RSYNC
+# define O_RSYNC 0
+#endif
+
+#ifndef O_SEARCH
+# define O_SEARCH O_RDONLY /* This is often close enough in older systems.  */
+#endif
+
+#ifndef O_SYNC
+# define O_SYNC 0
+#endif
+
+#ifndef O_TTY_INIT
+# define O_TTY_INIT 0
+#endif
+
+#if ~O_ACCMODE & (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
+# undef O_ACCMODE
+# define O_ACCMODE (O_RDONLY | O_WRONLY | O_RDWR | O_EXEC | O_SEARCH)
+#endif
+
+/* For systems that distinguish between text and binary I/O.
+   O_BINARY is usually declared in fcntl.h  */
+#if !defined O_BINARY && defined _O_BINARY
+  /* For MSC-compatible compilers.  */
+# define O_BINARY _O_BINARY
+# define O_TEXT _O_TEXT
+#endif
+
+#if defined __BEOS__ || defined __HAIKU__
+  /* BeOS 5 and Haiku have O_BINARY and O_TEXT, but they have no effect.  */
+# undef O_BINARY
+# undef O_TEXT
+#endif
+
+#ifndef O_BINARY
+# define O_BINARY 0
+# define O_TEXT 0
+#endif
+
+/* Fix up the AT_* macros.  */
+
+/* Work around a bug in Solaris 9 and 10: AT_FDCWD is positive.  Its
+   value exceeds INT_MAX, so its use as an int doesn't conform to the
+   C standard, and GCC and Sun C complain in some cases.  If the bug
+   is present, undef AT_FDCWD here, so it can be redefined below.  */
+#if 0 < AT_FDCWD && AT_FDCWD == 0xffd19553
+# undef AT_FDCWD
+#endif
+
+/* Use the same bit pattern as Solaris 9, but with the proper
+   signedness.  The bit pattern is important, in case this actually is
+   Solaris with the above workaround.  */
+#ifndef AT_FDCWD
+# define AT_FDCWD (-3041965)
+#endif
+
+/* Use the same values as Solaris 9.  This shouldn't matter, but
+   there's no real reason to differ.  */
+#ifndef AT_SYMLINK_NOFOLLOW
+# define AT_SYMLINK_NOFOLLOW 4096
+#endif
+
+#ifndef AT_REMOVEDIR
+# define AT_REMOVEDIR 1
+#endif
+
+/* Solaris 9 lacks these two, so just pick unique values.  */
+#ifndef AT_SYMLINK_FOLLOW
+# define AT_SYMLINK_FOLLOW 2
+#endif
+
+#ifndef AT_EACCESS
+# define AT_EACCESS 4
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_FCNTL_H */
+
+
diff --git a/headers-mingw/intprops.h b/headers-mingw/intprops.h
new file mode 100644
index 0000000..9702aec
--- /dev/null
+++ b/headers-mingw/intprops.h
@@ -0,0 +1,455 @@
+/* intprops.h -- properties of integer types
+
+   Copyright (C) 2001-2018 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify it
+   under the terms of the GNU Lesser General Public License as published
+   by the Free Software Foundation; either version 2.1 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+#ifndef _GL_INTPROPS_H
+#define _GL_INTPROPS_H
+
+#include <limits.h>
+
+/* Return a value with the common real type of E and V and the value of V.
+   Do not evaluate E.  */
+#define _GL_INT_CONVERT(e, v) ((1 ? 0 : (e)) + (v))
+
+/* Act like _GL_INT_CONVERT (E, -V) but work around a bug in IRIX 6.5 cc; see
+   <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00406.html>.  */
+#define _GL_INT_NEGATE_CONVERT(e, v) ((1 ? 0 : (e)) - (v))
+
+/* The extra casts in the following macros work around compiler bugs,
+   e.g., in Cray C 5.0.3.0.  */
+
+/* True if the arithmetic type T is an integer type.  bool counts as
+   an integer.  */
+#define TYPE_IS_INTEGER(t) ((t) 1.5 == 1)
+
+/* True if the real type T is signed.  */
+#define TYPE_SIGNED(t) (! ((t) 0 < (t) -1))
+
+/* Return 1 if the real expression E, after promotion, has a
+   signed or floating type.  Do not evaluate E.  */
+#define EXPR_SIGNED(e) (_GL_INT_NEGATE_CONVERT (e, 1) < 0)
+
+
+/* Minimum and maximum values for integer types and expressions.  */
+
+/* The width in bits of the integer type or expression T.
+   Do not evaluate T.
+   Padding bits are not supported; this is checked at compile-time below.  */
+#define TYPE_WIDTH(t) (sizeof (t) * CHAR_BIT)
+
+/* The maximum and minimum values for the integer type T.  */
+#define TYPE_MINIMUM(t) ((t) ~ TYPE_MAXIMUM (t))
+#define TYPE_MAXIMUM(t)                                                 \
+  ((t) (! TYPE_SIGNED (t)                                               \
+        ? (t) -1                                                        \
+        : ((((t) 1 << (TYPE_WIDTH (t) - 2)) - 1) * 2 + 1)))
+
+/* The maximum and minimum values for the type of the expression E,
+   after integer promotion.  E is not evaluated.  */
+#define _GL_INT_MINIMUM(e)                                              \
+  (EXPR_SIGNED (e)                                                      \
+   ? ~ _GL_SIGNED_INT_MAXIMUM (e)                                       \
+   : _GL_INT_CONVERT (e, 0))
+#define _GL_INT_MAXIMUM(e)                                              \
+  (EXPR_SIGNED (e)                                                      \
+   ? _GL_SIGNED_INT_MAXIMUM (e)                                         \
+   : _GL_INT_NEGATE_CONVERT (e, 1))
+#define _GL_SIGNED_INT_MAXIMUM(e)                                       \
+  (((_GL_INT_CONVERT (e, 1) << (TYPE_WIDTH ((e) + 0) - 2)) - 1) * 2 + 1)
+
+/* Work around OpenVMS incompatibility with C99.  */
+#if !defined LLONG_MAX && defined __INT64_MAX
+# define LLONG_MAX __INT64_MAX
+# define LLONG_MIN __INT64_MIN
+#endif
+
+/* This include file assumes that signed types are two's complement without
+   padding bits; the above macros have undefined behavior otherwise.
+   If this is a problem for you, please let us know how to fix it for your host.
+   This assumption is tested by the intprops-tests module.  */
+
+/* Does the __typeof__ keyword work?  This could be done by
+   'configure', but for now it's easier to do it by hand.  */
+#if (2 <= __GNUC__ \
+     || (1210 <= __IBMC__ && defined __IBM__TYPEOF__) \
+     || (0x5110 <= __SUNPRO_C && !__STDC__))
+# define _GL_HAVE___TYPEOF__ 1
+#else
+# define _GL_HAVE___TYPEOF__ 0
+#endif
+
+/* Return 1 if the integer type or expression T might be signed.  Return 0
+   if it is definitely unsigned.  This macro does not evaluate its argument,
+   and expands to an integer constant expression.  */
+#if _GL_HAVE___TYPEOF__
+# define _GL_SIGNED_TYPE_OR_EXPR(t) TYPE_SIGNED (__typeof__ (t))
+#else
+# define _GL_SIGNED_TYPE_OR_EXPR(t) 1
+#endif
+
+/* Bound on length of the string representing an unsigned integer
+   value representable in B bits.  log10 (2.0) < 146/485.  The
+   smallest value of B where this bound is not tight is 2621.  */
+#define INT_BITS_STRLEN_BOUND(b) (((b) * 146 + 484) / 485)
+
+/* Bound on length of the string representing an integer type or expression T.
+   Subtract 1 for the sign bit if T is signed, and then add 1 more for
+   a minus sign if needed.
+
+   Because _GL_SIGNED_TYPE_OR_EXPR sometimes returns 0 when its argument is
+   signed, this macro may overestimate the true bound by one byte when
+   applied to unsigned types of size 2, 4, 16, ... bytes.  */
+#define INT_STRLEN_BOUND(t)                                     \
+  (INT_BITS_STRLEN_BOUND (TYPE_WIDTH (t) - _GL_SIGNED_TYPE_OR_EXPR (t)) \
+   + _GL_SIGNED_TYPE_OR_EXPR (t))
+
+/* Bound on buffer size needed to represent an integer type or expression T,
+   including the terminating null.  */
+#define INT_BUFSIZE_BOUND(t) (INT_STRLEN_BOUND (t) + 1)
+
+
+/* Range overflow checks.
+
+   The INT_<op>_RANGE_OVERFLOW macros return 1 if the corresponding C
+   operators might not yield numerically correct answers due to
+   arithmetic overflow.  They do not rely on undefined or
+   implementation-defined behavior.  Their implementations are simple
+   and straightforward, but they are a bit harder to use than the
+   INT_<op>_OVERFLOW macros described below.
+
+   Example usage:
+
+     long int i = ...;
+     long int j = ...;
+     if (INT_MULTIPLY_RANGE_OVERFLOW (i, j, LONG_MIN, LONG_MAX))
+       printf ("multiply would overflow");
+     else
+       printf ("product is %ld", i * j);
+
+   Restrictions on *_RANGE_OVERFLOW macros:
+
+   These macros do not check for all possible numerical problems or
+   undefined or unspecified behavior: they do not check for division
+   by zero, for bad shift counts, or for shifting negative numbers.
+
+   These macros may evaluate their arguments zero or multiple times,
+   so the arguments should not have side effects.  The arithmetic
+   arguments (including the MIN and MAX arguments) must be of the same
+   integer type after the usual arithmetic conversions, and the type
+   must have minimum value MIN and maximum MAX.  Unsigned types should
+   use a zero MIN of the proper type.
+
+   These macros are tuned for constant MIN and MAX.  For commutative
+   operations such as A + B, they are also tuned for constant B.  */
+
+/* Return 1 if A + B would overflow in [MIN,MAX] arithmetic.
+   See above for restrictions.  */
+#define INT_ADD_RANGE_OVERFLOW(a, b, min, max)          \
+  ((b) < 0                                              \
+   ? (a) < (min) - (b)                                  \
+   : (max) - (b) < (a))
+
+/* Return 1 if A - B would overflow in [MIN,MAX] arithmetic.
+   See above for restrictions.  */
+#define INT_SUBTRACT_RANGE_OVERFLOW(a, b, min, max)     \
+  ((b) < 0                                              \
+   ? (max) + (b) < (a)                                  \
+   : (a) < (min) + (b))
+
+/* Return 1 if - A would overflow in [MIN,MAX] arithmetic.
+   See above for restrictions.  */
+#define INT_NEGATE_RANGE_OVERFLOW(a, min, max)          \
+  ((min) < 0                                            \
+   ? (a) < - (max)                                      \
+   : 0 < (a))
+
+/* Return 1 if A * B would overflow in [MIN,MAX] arithmetic.
+   See above for restrictions.  Avoid && and || as they tickle
+   bugs in Sun C 5.11 2010/08/13 and other compilers; see
+   <https://lists.gnu.org/r/bug-gnulib/2011-05/msg00401.html>.  */
+#define INT_MULTIPLY_RANGE_OVERFLOW(a, b, min, max)     \
+  ((b) < 0                                              \
+   ? ((a) < 0                                           \
+      ? (a) < (max) / (b)                               \
+      : (b) == -1                                       \
+      ? 0                                               \
+      : (min) / (b) < (a))                              \
+   : (b) == 0                                           \
+   ? 0                                                  \
+   : ((a) < 0                                           \
+      ? (a) < (min) / (b)                               \
+      : (max) / (b) < (a)))
+
+/* Return 1 if A / B would overflow in [MIN,MAX] arithmetic.
+   See above for restrictions.  Do not check for division by zero.  */
+#define INT_DIVIDE_RANGE_OVERFLOW(a, b, min, max)       \
+  ((min) < 0 && (b) == -1 && (a) < - (max))
+
+/* Return 1 if A % B would overflow in [MIN,MAX] arithmetic.
+   See above for restrictions.  Do not check for division by zero.
+   Mathematically, % should never overflow, but on x86-like hosts
+   INT_MIN % -1 traps, and the C standard permits this, so treat this
+   as an overflow too.  */
+#define INT_REMAINDER_RANGE_OVERFLOW(a, b, min, max)    \
+  INT_DIVIDE_RANGE_OVERFLOW (a, b, min, max)
+
+/* Return 1 if A << B would overflow in [MIN,MAX] arithmetic.
+   See above for restrictions.  Here, MIN and MAX are for A only, and B need
+   not be of the same type as the other arguments.  The C standard says that
+   behavior is undefined for shifts unless 0 <= B < wordwidth, and that when
+   A is negative then A << B has undefined behavior and A >> B has
+   implementation-defined behavior, but do not check these other
+   restrictions.  */
+#define INT_LEFT_SHIFT_RANGE_OVERFLOW(a, b, min, max)   \
+  ((a) < 0                                              \
+   ? (a) < (min) >> (b)                                 \
+   : (max) >> (b) < (a))
+
+/* True if __builtin_add_overflow (A, B, P) works when P is non-null.  */
+#if 5 <= __GNUC__ && !defined __ICC
+# define _GL_HAS_BUILTIN_OVERFLOW 1
+#else
+# define _GL_HAS_BUILTIN_OVERFLOW 0
+#endif
+
+/* True if __builtin_add_overflow_p (A, B, C) works.  */
+#define _GL_HAS_BUILTIN_OVERFLOW_P (7 <= __GNUC__)
+
+/* The _GL*_OVERFLOW macros have the same restrictions as the
+   *_RANGE_OVERFLOW macros, except that they do not assume that operands
+   (e.g., A and B) have the same type as MIN and MAX.  Instead, they assume
+   that the result (e.g., A + B) has that type.  */
+#if _GL_HAS_BUILTIN_OVERFLOW_P
+# define _GL_ADD_OVERFLOW(a, b, min, max)                               \
+   __builtin_add_overflow_p (a, b, (__typeof__ ((a) + (b))) 0)
+# define _GL_SUBTRACT_OVERFLOW(a, b, min, max)                          \
+   __builtin_sub_overflow_p (a, b, (__typeof__ ((a) - (b))) 0)
+# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                          \
+   __builtin_mul_overflow_p (a, b, (__typeof__ ((a) * (b))) 0)
+#else
+# define _GL_ADD_OVERFLOW(a, b, min, max)                                \
+   ((min) < 0 ? INT_ADD_RANGE_OVERFLOW (a, b, min, max)                  \
+    : (a) < 0 ? (b) <= (a) + (b)                                         \
+    : (b) < 0 ? (a) <= (a) + (b)                                         \
+    : (a) + (b) < (b))
+# define _GL_SUBTRACT_OVERFLOW(a, b, min, max)                           \
+   ((min) < 0 ? INT_SUBTRACT_RANGE_OVERFLOW (a, b, min, max)             \
+    : (a) < 0 ? 1                                                        \
+    : (b) < 0 ? (a) - (b) <= (a)                                         \
+    : (a) < (b))
+# define _GL_MULTIPLY_OVERFLOW(a, b, min, max)                           \
+   (((min) == 0 && (((a) < 0 && 0 < (b)) || ((b) < 0 && 0 < (a))))       \
+    || INT_MULTIPLY_RANGE_OVERFLOW (a, b, min, max))
+#endif
+#define _GL_DIVIDE_OVERFLOW(a, b, min, max)                             \
+  ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max)  \
+   : (a) < 0 ? (b) <= (a) + (b) - 1                                     \
+   : (b) < 0 && (a) + (b) <= (a))
+#define _GL_REMAINDER_OVERFLOW(a, b, min, max)                          \
+  ((min) < 0 ? (b) == _GL_INT_NEGATE_CONVERT (min, 1) && (a) < - (max)  \
+   : (a) < 0 ? (a) % (b) != ((max) - (b) + 1) % (b)                     \
+   : (b) < 0 && ! _GL_UNSIGNED_NEG_MULTIPLE (a, b, max))
+
+/* Return a nonzero value if A is a mathematical multiple of B, where
+   A is unsigned, B is negative, and MAX is the maximum value of A's
+   type.  A's type must be the same as (A % B)'s type.  Normally (A %
+   -B == 0) suffices, but things get tricky if -B would overflow.  */
+#define _GL_UNSIGNED_NEG_MULTIPLE(a, b, max)                            \
+  (((b) < -_GL_SIGNED_INT_MAXIMUM (b)                                   \
+    ? (_GL_SIGNED_INT_MAXIMUM (b) == (max)                              \
+       ? (a)                                                            \
+       : (a) % (_GL_INT_CONVERT (a, _GL_SIGNED_INT_MAXIMUM (b)) + 1))   \
+    : (a) % - (b))                                                      \
+   == 0)
+
+/* Check for integer overflow, and report low order bits of answer.
+
+   The INT_<op>_OVERFLOW macros return 1 if the corresponding C operators
+   might not yield numerically correct answers due to arithmetic overflow.
+   The INT_<op>_WRAPV macros also store the low-order bits of the answer.
+   These macros work correctly on all known practical hosts, and do not rely
+   on undefined behavior due to signed arithmetic overflow.
+
+   Example usage, assuming A and B are long int:
+
+     if (INT_MULTIPLY_OVERFLOW (a, b))
+       printf ("result would overflow\n");
+     else
+       printf ("result is %ld (no overflow)\n", a * b);
+
+   Example usage with WRAPV flavor:
+
+     long int result;
+     bool overflow = INT_MULTIPLY_WRAPV (a, b, &result);
+     printf ("result is %ld (%s)\n", result,
+             overflow ? "after overflow" : "no overflow");
+
+   Restrictions on these macros:
+
+   These macros do not check for all possible numerical problems or
+   undefined or unspecified behavior: they do not check for division
+   by zero, for bad shift counts, or for shifting negative numbers.
+
+   These macros may evaluate their arguments zero or multiple times, so the
+   arguments should not have side effects.
+
+   The WRAPV macros are not constant expressions.  They support only
+   +, binary -, and *.  The result type must be signed.
+
+   These macros are tuned for their last argument being a constant.
+
+   Return 1 if the integer expressions A * B, A - B, -A, A * B, A / B,
+   A % B, and A << B would overflow, respectively.  */
+
+#define INT_ADD_OVERFLOW(a, b) \
+  _GL_BINARY_OP_OVERFLOW (a, b, _GL_ADD_OVERFLOW)
+#define INT_SUBTRACT_OVERFLOW(a, b) \
+  _GL_BINARY_OP_OVERFLOW (a, b, _GL_SUBTRACT_OVERFLOW)
+#if _GL_HAS_BUILTIN_OVERFLOW_P
+# define INT_NEGATE_OVERFLOW(a) INT_SUBTRACT_OVERFLOW (0, a)
+#else
+# define INT_NEGATE_OVERFLOW(a) \
+   INT_NEGATE_RANGE_OVERFLOW (a, _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
+#endif
+#define INT_MULTIPLY_OVERFLOW(a, b) \
+  _GL_BINARY_OP_OVERFLOW (a, b, _GL_MULTIPLY_OVERFLOW)
+#define INT_DIVIDE_OVERFLOW(a, b) \
+  _GL_BINARY_OP_OVERFLOW (a, b, _GL_DIVIDE_OVERFLOW)
+#define INT_REMAINDER_OVERFLOW(a, b) \
+  _GL_BINARY_OP_OVERFLOW (a, b, _GL_REMAINDER_OVERFLOW)
+#define INT_LEFT_SHIFT_OVERFLOW(a, b) \
+  INT_LEFT_SHIFT_RANGE_OVERFLOW (a, b, \
+                                 _GL_INT_MINIMUM (a), _GL_INT_MAXIMUM (a))
+
+/* Return 1 if the expression A <op> B would overflow,
+   where OP_RESULT_OVERFLOW (A, B, MIN, MAX) does the actual test,
+   assuming MIN and MAX are the minimum and maximum for the result type.
+   Arguments should be free of side effects.  */
+#define _GL_BINARY_OP_OVERFLOW(a, b, op_result_overflow)        \
+  op_result_overflow (a, b,                                     \
+                      _GL_INT_MINIMUM (_GL_INT_CONVERT (a, b)), \
+                      _GL_INT_MAXIMUM (_GL_INT_CONVERT (a, b)))
+
+/* Store the low-order bits of A + B, A - B, A * B, respectively, into *R.
+   Return 1 if the result overflows.  See above for restrictions.  */
+#define INT_ADD_WRAPV(a, b, r) \
+  _GL_INT_OP_WRAPV (a, b, r, +, __builtin_add_overflow, INT_ADD_OVERFLOW)
+#define INT_SUBTRACT_WRAPV(a, b, r) \
+  _GL_INT_OP_WRAPV (a, b, r, -, __builtin_sub_overflow, INT_SUBTRACT_OVERFLOW)
+#define INT_MULTIPLY_WRAPV(a, b, r) \
+  _GL_INT_OP_WRAPV (a, b, r, *, __builtin_mul_overflow, INT_MULTIPLY_OVERFLOW)
+
+/* Nonzero if this compiler has GCC bug 68193 or Clang bug 25390.  See:
+   https://gcc.gnu.org/bugzilla/show_bug.cgi?id=68193
+   https://llvm.org/bugs/show_bug.cgi?id=25390
+   For now, assume all versions of GCC-like compilers generate bogus
+   warnings for _Generic.  This matters only for older compilers that
+   lack __builtin_add_overflow.  */
+#if __GNUC__
+# define _GL__GENERIC_BOGUS 1
+#else
+# define _GL__GENERIC_BOGUS 0
+#endif
+
+/* Store the low-order bits of A <op> B into *R, where OP specifies
+   the operation.  BUILTIN is the builtin operation, and OVERFLOW the
+   overflow predicate.  Return 1 if the result overflows.  See above
+   for restrictions.  */
+#if _GL_HAS_BUILTIN_OVERFLOW
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) builtin (a, b, r)
+#elif 201112 <= __STDC_VERSION__ && !_GL__GENERIC_BOGUS
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
+   (_Generic \
+    (*(r), \
+     signed char: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        signed char, SCHAR_MIN, SCHAR_MAX), \
+     short int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        short int, SHRT_MIN, SHRT_MAX), \
+     int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                        int, INT_MIN, INT_MAX), \
+     long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        long int, LONG_MIN, LONG_MAX), \
+     long long int: \
+       _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                        long long int, LLONG_MIN, LLONG_MAX)))
+#else
+# define _GL_INT_OP_WRAPV(a, b, r, op, builtin, overflow) \
+   (sizeof *(r) == sizeof (signed char) \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                       signed char, SCHAR_MIN, SCHAR_MAX) \
+    : sizeof *(r) == sizeof (short int) \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                       short int, SHRT_MIN, SHRT_MAX) \
+    : sizeof *(r) == sizeof (int) \
+    ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned int, \
+                       int, INT_MIN, INT_MAX) \
+    : _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow))
+# ifdef LLONG_MAX
+#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+    (sizeof *(r) == sizeof (long int) \
+     ? _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                        long int, LONG_MIN, LONG_MAX) \
+     : _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long long int, \
+                        long long int, LLONG_MIN, LLONG_MAX))
+# else
+#  define _GL_INT_OP_WRAPV_LONGISH(a, b, r, op, overflow) \
+    _GL_INT_OP_CALC (a, b, r, op, overflow, unsigned long int, \
+                     long int, LONG_MIN, LONG_MAX)
+# endif
+#endif
+
+/* Store the low-order bits of A <op> B into *R, where the operation
+   is given by OP.  Use the unsigned type UT for calculation to avoid
+   overflow problems.  *R's type is T, with extrema TMIN and TMAX.
+   T must be a signed integer type.  Return 1 if the result overflows.  */
+#define _GL_INT_OP_CALC(a, b, r, op, overflow, ut, t, tmin, tmax) \
+  (sizeof ((a) op (b)) < sizeof (t) \
+   ? _GL_INT_OP_CALC1 ((t) (a), (t) (b), r, op, overflow, ut, t, tmin, tmax) \
+   : _GL_INT_OP_CALC1 (a, b, r, op, overflow, ut, t, tmin, tmax))
+#define _GL_INT_OP_CALC1(a, b, r, op, overflow, ut, t, tmin, tmax) \
+  ((overflow (a, b) \
+    || (EXPR_SIGNED ((a) op (b)) && ((a) op (b)) < (tmin)) \
+    || (tmax) < ((a) op (b))) \
+   ? (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 1) \
+   : (*(r) = _GL_INT_OP_WRAPV_VIA_UNSIGNED (a, b, op, ut, t), 0))
+
+/* Return the low-order bits of A <op> B, where the operation is given
+   by OP.  Use the unsigned type UT for calculation to avoid undefined
+   behavior on signed integer overflow, and convert the result to type T.
+   UT is at least as wide as T and is no narrower than unsigned int,
+   T is two's complement, and there is no padding or trap representations.
+   Assume that converting UT to T yields the low-order bits, as is
+   done in all known two's-complement C compilers.  E.g., see:
+   https://gcc.gnu.org/onlinedocs/gcc/Integers-implementation.html
+
+   According to the C standard, converting UT to T yields an
+   implementation-defined result or signal for values outside T's
+   range.  However, code that works around this theoretical problem
+   runs afoul of a compiler bug in Oracle Studio 12.3 x86.  See:
+   https://lists.gnu.org/r/bug-gnulib/2017-04/msg00049.html
+   As the compiler bug is real, don't try to work around the
+   theoretical problem.  */
+
+#define _GL_INT_OP_WRAPV_VIA_UNSIGNED(a, b, op, ut, t) \
+  ((t) ((ut) (a) op (ut) (b)))
+
+#endif /* _GL_INTPROPS_H */
diff --git a/headers-mingw/langinfo.h b/headers-mingw/langinfo.h
new file mode 100644
index 0000000..43244cd
--- /dev/null
+++ b/headers-mingw/langinfo.h
@@ -0,0 +1,139 @@
+/* Substitute for and wrapper around <langinfo.h>.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+/*
+ * POSIX <langinfo.h> for platforms that lack it or have an incomplete one.
+ * <http://www.opengroup.org/onlinepubs/9699919799/basedefs/langinfo.h.html>
+ */
+
+#ifndef _GL_LANGINFO_H
+#define _GL_LANGINFO_H
+
+
+/* A platform that lacks <langinfo.h>.  */
+
+/* Assume that it also lacks <nl_types.h> and the nl_item type.  */
+# if !GNULIB_defined_nl_item
+typedef int nl_item;
+#  define GNULIB_defined_nl_item 1
+# endif
+
+/* nl_langinfo items of the LC_CTYPE category */
+# define CODESET     10000
+/* nl_langinfo items of the LC_NUMERIC category */
+# define RADIXCHAR   10001
+# define DECIMAL_POINT RADIXCHAR
+# define THOUSEP     10002
+# define THOUSANDS_SEP THOUSEP
+# define GROUPING    10114
+/* nl_langinfo items of the LC_TIME category */
+# define D_T_FMT     10003
+# define D_FMT       10004
+# define T_FMT       10005
+# define T_FMT_AMPM  10006
+# define AM_STR      10007
+# define PM_STR      10008
+# define DAY_1       10009
+# define DAY_2       (DAY_1 + 1)
+# define DAY_3       (DAY_1 + 2)
+# define DAY_4       (DAY_1 + 3)
+# define DAY_5       (DAY_1 + 4)
+# define DAY_6       (DAY_1 + 5)
+# define DAY_7       (DAY_1 + 6)
+# define ABDAY_1     10016
+# define ABDAY_2     (ABDAY_1 + 1)
+# define ABDAY_3     (ABDAY_1 + 2)
+# define ABDAY_4     (ABDAY_1 + 3)
+# define ABDAY_5     (ABDAY_1 + 4)
+# define ABDAY_6     (ABDAY_1 + 5)
+# define ABDAY_7     (ABDAY_1 + 6)
+# define MON_1       10023
+# define MON_2       (MON_1 + 1)
+# define MON_3       (MON_1 + 2)
+# define MON_4       (MON_1 + 3)
+# define MON_5       (MON_1 + 4)
+# define MON_6       (MON_1 + 5)
+# define MON_7       (MON_1 + 6)
+# define MON_8       (MON_1 + 7)
+# define MON_9       (MON_1 + 8)
+# define MON_10      (MON_1 + 9)
+# define MON_11      (MON_1 + 10)
+# define MON_12      (MON_1 + 11)
+# define ALTMON_1    10200
+# define ALTMON_2    (ALTMON_1 + 1)
+# define ALTMON_3    (ALTMON_1 + 2)
+# define ALTMON_4    (ALTMON_1 + 3)
+# define ALTMON_5    (ALTMON_1 + 4)
+# define ALTMON_6    (ALTMON_1 + 5)
+# define ALTMON_7    (ALTMON_1 + 6)
+# define ALTMON_8    (ALTMON_1 + 7)
+# define ALTMON_9    (ALTMON_1 + 8)
+# define ALTMON_10   (ALTMON_1 + 9)
+# define ALTMON_11   (ALTMON_1 + 10)
+# define ALTMON_12   (ALTMON_1 + 11)
+# define ABMON_1     10035
+# define ABMON_2     (ABMON_1 + 1)
+# define ABMON_3     (ABMON_1 + 2)
+# define ABMON_4     (ABMON_1 + 3)
+# define ABMON_5     (ABMON_1 + 4)
+# define ABMON_6     (ABMON_1 + 5)
+# define ABMON_7     (ABMON_1 + 6)
+# define ABMON_8     (ABMON_1 + 7)
+# define ABMON_9     (ABMON_1 + 8)
+# define ABMON_10    (ABMON_1 + 9)
+# define ABMON_11    (ABMON_1 + 10)
+# define ABMON_12    (ABMON_1 + 11)
+# define ERA         10047
+# define ERA_D_FMT   10048
+# define ERA_D_T_FMT 10049
+# define ERA_T_FMT   10050
+# define ALT_DIGITS  10051
+/* nl_langinfo items of the LC_MONETARY category */
+# define CRNCYSTR    10052
+# define CURRENCY_SYMBOL   CRNCYSTR
+# define INT_CURR_SYMBOL   10100
+# define MON_DECIMAL_POINT 10101
+# define MON_THOUSANDS_SEP 10102
+# define MON_GROUPING      10103
+# define POSITIVE_SIGN     10104
+# define NEGATIVE_SIGN     10105
+# define FRAC_DIGITS       10106
+# define INT_FRAC_DIGITS   10107
+# define P_CS_PRECEDES     10108
+# define N_CS_PRECEDES     10109
+# define P_SEP_BY_SPACE    10110
+# define N_SEP_BY_SPACE    10111
+# define P_SIGN_POSN       10112
+# define N_SIGN_POSN       10113
+/* nl_langinfo items of the LC_MESSAGES category */
+# define YESEXPR     10053
+# define NOEXPR      10054
+
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+/* Declare overridden functions.  */
+
+
+/* Return a piece of locale dependent information.
+   Note: The difference between nl_langinfo (CODESET) and locale_charset ()
+   is that the latter normalizes the encoding names to GNU conventions.  */
+
+extern char * nl_langinfo (nl_item item);
+
+#endif /* _GL_LANGINFO_H */
diff --git a/headers-mingw/libc-config.h b/headers-mingw/libc-config.h
new file mode 100644
index 0000000..a352393
--- /dev/null
+++ b/headers-mingw/libc-config.h
@@ -0,0 +1,174 @@
+/* System definitions for code taken from the GNU C Library
+
+   Copyright 2017-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with this program; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+/* Written by Paul Eggert.  */
+
+/* This is intended to be a good-enough substitute for glibc system
+   macros like those defined in <sys/cdefs.h>, so that Gnulib code
+   shared with glibc can do this as the first #include:
+
+     #ifndef _LIBC
+     # include <libc-config.h>
+     #endif
+
+   When compiled as part of glibc this is a no-op; when compiled as
+   part of Gnulib this includes Gnulib's <config.h> and defines macros
+   that glibc library code would normally assume.  */
+
+#include <config.h>
+
+/* On glibc this includes <features.h> and <sys/cdefs.h> and #defines
+   _FEATURES_H, __WORDSIZE, and __set_errno.  On FreeBSD 11 it
+   includes <sys/cdefs.h> which defines __nonnull.  Elsewhere it
+   is harmless.  */
+#include <errno.h>
+
+/* From glibc <errno.h>.  */
+#ifndef __set_errno
+# define __set_errno(val) (errno = (val))
+#endif
+
+/* From glibc <features.h>.  */
+
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+#  define __GNUC_PREREQ(maj, min) ((maj) < __GNUC__ + ((min) <= __GNUC_MINOR__))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+#ifndef __glibc_clang_prereq
+# if defined __clang_major__ && defined __clang_minor__
+#  define __glibc_clang_prereq(maj, min) \
+     ((maj) < __clang_major__ + ((min) <= __clang_minor__))
+# else
+#  define __glibc_clang_prereq(maj, min) 0
+# endif
+#endif
+
+
+/* Prepare to include <cdefs.h>, which is our copy of glibc
+   <sys/cdefs.h>.  */
+
+/* Define _FEATURES_H so that <cdefs.h> does not include <features.h>.  */
+#ifndef _FEATURES_H
+# define _FEATURES_H 1
+#endif
+/* Define __WORDSIZE so that <cdefs.h> does not attempt to include
+   nonexistent files.  Make it a syntax error, since Gnulib does not
+   use __WORDSIZE now, and if Gnulib uses it later the syntax error
+   will let us know that __WORDSIZE needs configuring.  */
+#ifndef __WORDSIZE
+# define __WORDSIZE %%%
+#endif
+/* Undef the macros unconditionally defined by our copy of glibc
+   <sys/cdefs.h>, so that they do not clash with any system-defined
+   versions.  */
+#undef _SYS_CDEFS_H
+#undef __ASMNAME
+#undef __ASMNAME2
+#undef __BEGIN_DECLS
+#undef __CONCAT
+#undef __END_DECLS
+#undef __HAVE_GENERIC_SELECTION
+#undef __LDBL_COMPAT
+#undef __LDBL_REDIR
+#undef __LDBL_REDIR1
+#undef __LDBL_REDIR1_DECL
+#undef __LDBL_REDIR1_NTH
+#undef __LDBL_REDIR_DECL
+#undef __LDBL_REDIR_NTH
+#undef __LEAF
+#undef __LEAF_ATTR
+#undef __NTH
+#undef __NTHNL
+#undef __P
+#undef __PMT
+#undef __REDIRECT
+#undef __REDIRECT_LDBL
+#undef __REDIRECT_NTH
+#undef __REDIRECT_NTHNL
+#undef __REDIRECT_NTH_LDBL
+#undef __STRING
+#undef __THROW
+#undef __THROWNL
+#undef __always_inline
+#undef __attribute__
+#undef __attribute_alloc_size__
+#undef __attribute_artificial__
+#undef __attribute_const__
+#undef __attribute_deprecated__
+#undef __attribute_deprecated_msg__
+#undef __attribute_format_arg__
+#undef __attribute_format_strfmon__
+#undef __attribute_malloc__
+#undef __attribute_noinline__
+#undef __attribute_nonstring__
+#undef __attribute_pure__
+#undef __attribute_used__
+#undef __attribute_warn_unused_result__
+#undef __bos
+#undef __bos0
+#undef __errordecl
+#undef __extension__
+#undef __extern_always_inline
+#undef __extern_inline
+#undef __flexarr
+#undef __fortify_function
+#undef __glibc_c99_flexarr_available
+#undef __glibc_clang_has_extension
+#undef __glibc_likely
+#undef __glibc_macro_warning
+#undef __glibc_macro_warning1
+#undef __glibc_unlikely
+#undef __inline
+#undef __ptr_t
+#undef __restrict
+#undef __restrict_arr
+#undef __va_arg_pack
+#undef __va_arg_pack_len
+#undef __warnattr
+#undef __warndecl
+
+/* Include our copy of glibc <sys/cdefs.h>.  */
+#include "sys_cdefs.h"
+
+/* <cdefs.h> __inline is too pessimistic for non-GCC.  */
+#undef __inline
+#ifndef HAVE___INLINE
+# if 199901 <= __STDC_VERSION__ || defined inline
+#  define __inline inline
+# else
+#  define __inline
+# endif
+#endif
+
+
+/* A substitute for glibc <libc-symbols.h>, good enough for Gnulib.  */
+#define attribute_hidden
+#define libc_hidden_proto(name, ...)
+#define libc_hidden_def(name)
+#define libc_hidden_weak(name)
+#define libc_hidden_ver(local, name)
+#define strong_alias(name, aliasname)
+#define weak_alias(name, aliasname)
+
+/* A substitute for glibc <shlib-compat.h>, good enough for Gnulib.  */
+#define SHLIB_COMPAT(lib, introduced, obsoleted) 0
+#define versioned_symbol(lib, local, symbol, version)
diff --git a/headers-mingw/poll.h b/headers-mingw/poll.h
new file mode 100644
index 0000000..fd3fb64
--- /dev/null
+++ b/headers-mingw/poll.h
@@ -0,0 +1,76 @@
+/* Header for poll(2) emulation
+   Contributed by Paolo Bonzini.
+
+   Copyright 2001-2003, 2007, 2009-2018 Free Software Foundation, Inc.
+
+   This file is part of gnulib.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_POLL_H
+
+#define _GL_POLL_H
+
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+#if !HAVE_POLL_H
+
+/* fake a poll(2) environment */
+# define POLLIN      0x0001      /* any readable data available   */
+# define POLLPRI     0x0002      /* OOB/Urgent readable data      */
+# define POLLOUT     0x0004      /* file descriptor is writable   */
+# define POLLERR     0x0008      /* some poll error occurred      */
+# define POLLHUP     0x0010      /* file descriptor was "hung up" */
+# define POLLNVAL    0x0020      /* requested events "invalid"    */
+# define POLLRDNORM  0x0040
+# define POLLRDBAND  0x0080
+# define POLLWRNORM  0x0100
+# define POLLWRBAND  0x0200
+
+# if !GNULIB_defined_poll_types
+#  if !(defined _WIN32 && ! defined __CYGWIN__)
+struct pollfd
+{
+  int fd;                       /* which file descriptor to poll */
+  short events;                 /* events we are interested in   */
+  short revents;                /* events found on return        */
+};
+
+#  else
+#include <winsock2.h>
+#  endif
+
+typedef unsigned long nfds_t;
+
+#  define GNULIB_defined_poll_types 1
+# endif
+
+/* Define INFTIM only if doing so conforms to POSIX.  */
+# if !defined (_POSIX_C_SOURCE) && !defined (_XOPEN_SOURCE)
+#  define INFTIM (-1)
+# endif
+
+#endif
+
+
+#  if !HAVE_POLL
+extern int poll (struct pollfd *pfd, nfds_t nfd, int timeout);
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_POLL_H */
diff --git a/headers-mingw/regex.h b/headers-mingw/regex.h
new file mode 100644
index 0000000..8d8160f
--- /dev/null
+++ b/headers-mingw/regex.h
@@ -0,0 +1,635 @@
+/* Definitions for data structures and routines for the regular
+   expression library.
+   Copyright (C) 1985, 1989-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _REGEX_H
+#define _REGEX_H 1
+
+#include <sys/types.h>
+
+/* Allow the use in C++ code.  */
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Define __USE_GNU to declare GNU extensions that violate the
+   POSIX name space rules.  */
+#ifdef _GNU_SOURCE
+# define __USE_GNU 1
+#endif
+
+#ifdef _REGEX_LARGE_OFFSETS
+
+/* Use types and values that are wide enough to represent signed and
+   unsigned byte offsets in memory.  This currently works only when
+   the regex code is used outside of the GNU C library; it is not yet
+   supported within glibc itself, and glibc users should not define
+   _REGEX_LARGE_OFFSETS.  */
+
+/* The type of object sizes.  */
+typedef size_t __re_size_t;
+
+/* The type of object sizes, in places where the traditional code
+   uses unsigned long int.  */
+typedef size_t __re_long_size_t;
+
+#else
+
+/* The traditional GNU regex implementation mishandles strings longer
+   than INT_MAX.  */
+typedef unsigned int __re_size_t;
+typedef unsigned long int __re_long_size_t;
+
+#endif
+
+/* The following two types have to be signed and unsigned integer type
+   wide enough to hold a value of a pointer.  For most ANSI compilers
+   ptrdiff_t and size_t should be likely OK.  Still size of these two
+   types is 2 for Microsoft C.  Ugh... */
+typedef long int s_reg_t;
+typedef unsigned long int active_reg_t;
+
+/* The following bits are used to determine the regexp syntax we
+   recognize.  The set/not-set meanings are chosen so that Emacs syntax
+   remains the value 0.  The bits are given in alphabetical order, and
+   the definitions shifted by one from the previous bit; thus, when we
+   add or remove a bit, only one other definition need change.  */
+typedef unsigned long int reg_syntax_t;
+
+/* If this bit is not set, then \ inside a bracket expression is literal.
+   If set, then such a \ quotes the following character.  */
+# define RE_BACKSLASH_ESCAPE_IN_LISTS ((unsigned long int) 1)
+
+/* If this bit is not set, then + and ? are operators, and \+ and \? are
+     literals.
+   If set, then \+ and \? are operators and + and ? are literals.  */
+# define RE_BK_PLUS_QM (RE_BACKSLASH_ESCAPE_IN_LISTS << 1)
+
+/* If this bit is set, then character classes are supported.  They are:
+     [:alpha:], [:upper:], [:lower:],  [:digit:], [:alnum:], [:xdigit:],
+     [:space:], [:print:], [:punct:], [:graph:], and [:cntrl:].
+   If not set, then character classes are not supported.  */
+# define RE_CHAR_CLASSES (RE_BK_PLUS_QM << 1)
+
+/* If this bit is set, then ^ and $ are always anchors (outside bracket
+     expressions, of course).
+   If this bit is not set, then it depends:
+	^  is an anchor if it is at the beginning of a regular
+	   expression or after an open-group or an alternation operator;
+	$  is an anchor if it is at the end of a regular expression, or
+	   before a close-group or an alternation operator.
+
+   This bit could be (re)combined with RE_CONTEXT_INDEP_OPS, because
+   POSIX draft 11.2 says that * etc. in leading positions is undefined.
+   We already implemented a previous draft which made those constructs
+   invalid, though, so we haven't changed the code back.  */
+# define RE_CONTEXT_INDEP_ANCHORS (RE_CHAR_CLASSES << 1)
+
+/* If this bit is set, then special characters are always special
+     regardless of where they are in the pattern.
+   If this bit is not set, then special characters are special only in
+     some contexts; otherwise they are ordinary.  Specifically,
+     * + ? and intervals are only special when not after the beginning,
+     open-group, or alternation operator.  */
+# define RE_CONTEXT_INDEP_OPS (RE_CONTEXT_INDEP_ANCHORS << 1)
+
+/* If this bit is set, then *, +, ?, and { cannot be first in an re or
+     immediately after an alternation or begin-group operator.  */
+# define RE_CONTEXT_INVALID_OPS (RE_CONTEXT_INDEP_OPS << 1)
+
+/* If this bit is set, then . matches newline.
+   If not set, then it doesn't.  */
+# define RE_DOT_NEWLINE (RE_CONTEXT_INVALID_OPS << 1)
+
+/* If this bit is set, then . doesn't match NUL.
+   If not set, then it does.  */
+# define RE_DOT_NOT_NULL (RE_DOT_NEWLINE << 1)
+
+/* If this bit is set, nonmatching lists [^...] do not match newline.
+   If not set, they do.  */
+# define RE_HAT_LISTS_NOT_NEWLINE (RE_DOT_NOT_NULL << 1)
+
+/* If this bit is set, either \{...\} or {...} defines an
+     interval, depending on RE_NO_BK_BRACES.
+   If not set, \{, \}, {, and } are literals.  */
+# define RE_INTERVALS (RE_HAT_LISTS_NOT_NEWLINE << 1)
+
+/* If this bit is set, +, ? and | aren't recognized as operators.
+   If not set, they are.  */
+# define RE_LIMITED_OPS (RE_INTERVALS << 1)
+
+/* If this bit is set, newline is an alternation operator.
+   If not set, newline is literal.  */
+# define RE_NEWLINE_ALT (RE_LIMITED_OPS << 1)
+
+/* If this bit is set, then '{...}' defines an interval, and \{ and \}
+     are literals.
+  If not set, then '\{...\}' defines an interval.  */
+# define RE_NO_BK_BRACES (RE_NEWLINE_ALT << 1)
+
+/* If this bit is set, (...) defines a group, and \( and \) are literals.
+   If not set, \(...\) defines a group, and ( and ) are literals.  */
+# define RE_NO_BK_PARENS (RE_NO_BK_BRACES << 1)
+
+/* If this bit is set, then \<digit> matches <digit>.
+   If not set, then \<digit> is a back-reference.  */
+# define RE_NO_BK_REFS (RE_NO_BK_PARENS << 1)
+
+/* If this bit is set, then | is an alternation operator, and \| is literal.
+   If not set, then \| is an alternation operator, and | is literal.  */
+# define RE_NO_BK_VBAR (RE_NO_BK_REFS << 1)
+
+/* If this bit is set, then an ending range point collating higher
+     than the starting range point, as in [z-a], is invalid.
+   If not set, then when ending range point collates higher than the
+     starting range point, the range is ignored.  */
+# define RE_NO_EMPTY_RANGES (RE_NO_BK_VBAR << 1)
+
+/* If this bit is set, then an unmatched ) is ordinary.
+   If not set, then an unmatched ) is invalid.  */
+# define RE_UNMATCHED_RIGHT_PAREN_ORD (RE_NO_EMPTY_RANGES << 1)
+
+/* If this bit is set, succeed as soon as we match the whole pattern,
+   without further backtracking.  */
+# define RE_NO_POSIX_BACKTRACKING (RE_UNMATCHED_RIGHT_PAREN_ORD << 1)
+
+/* If this bit is set, do not process the GNU regex operators.
+   If not set, then the GNU regex operators are recognized. */
+# define RE_NO_GNU_OPS (RE_NO_POSIX_BACKTRACKING << 1)
+
+/* If this bit is set, turn on internal regex debugging.
+   If not set, and debugging was on, turn it off.
+   This only works if regex.c is compiled -DDEBUG.
+   We define this bit always, so that all that's needed to turn on
+   debugging is to recompile regex.c; the calling code can always have
+   this bit set, and it won't affect anything in the normal case. */
+# define RE_DEBUG (RE_NO_GNU_OPS << 1)
+
+/* If this bit is set, a syntactically invalid interval is treated as
+   a string of ordinary characters.  For example, the ERE 'a{1' is
+   treated as 'a\{1'.  */
+# define RE_INVALID_INTERVAL_ORD (RE_DEBUG << 1)
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+# define RE_ICASE (RE_INVALID_INTERVAL_ORD << 1)
+
+/* This bit is used internally like RE_CONTEXT_INDEP_ANCHORS but only
+   for ^, because it is difficult to scan the regex backwards to find
+   whether ^ should be special.  */
+# define RE_CARET_ANCHORS_HERE (RE_ICASE << 1)
+
+/* If this bit is set, then \{ cannot be first in a regex or
+   immediately after an alternation, open-group or \} operator.  */
+# define RE_CONTEXT_INVALID_DUP (RE_CARET_ANCHORS_HERE << 1)
+
+/* If this bit is set, then no_sub will be set to 1 during
+   re_compile_pattern.  */
+# define RE_NO_SUB (RE_CONTEXT_INVALID_DUP << 1)
+
+
+/* This global variable defines the particular regexp syntax to use (for
+   some interfaces).  When a regexp is compiled, the syntax used is
+   stored in the pattern buffer, so changing this does not affect
+   already-compiled regexps.  */
+extern reg_syntax_t re_syntax_options;
+
+
+/* Define combinations of the above bits for the standard possibilities.
+   (The [[[ comments delimit what gets put into the Texinfo file, so
+   don't delete them!)  */
+/* [[[begin syntaxes]]] */
+# define RE_SYNTAX_EMACS 0
+
+# define RE_SYNTAX_AWK							\
+  (RE_BACKSLASH_ESCAPE_IN_LISTS   | RE_DOT_NOT_NULL			\
+   | RE_NO_BK_PARENS              | RE_NO_BK_REFS			\
+   | RE_NO_BK_VBAR                | RE_NO_EMPTY_RANGES			\
+   | RE_DOT_NEWLINE		  | RE_CONTEXT_INDEP_ANCHORS		\
+   | RE_CHAR_CLASSES							\
+   | RE_UNMATCHED_RIGHT_PAREN_ORD | RE_NO_GNU_OPS)
+
+# define RE_SYNTAX_GNU_AWK						\
+  ((RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS		\
+    | RE_INVALID_INTERVAL_ORD)						\
+   & ~(RE_DOT_NOT_NULL | RE_CONTEXT_INDEP_OPS				\
+      | RE_CONTEXT_INVALID_OPS ))
+
+# define RE_SYNTAX_POSIX_AWK						\
+  (RE_SYNTAX_POSIX_EXTENDED | RE_BACKSLASH_ESCAPE_IN_LISTS		\
+   | RE_INTERVALS	    | RE_NO_GNU_OPS				\
+   | RE_INVALID_INTERVAL_ORD)
+
+# define RE_SYNTAX_GREP							\
+  ((RE_SYNTAX_POSIX_BASIC | RE_NEWLINE_ALT)				\
+   & ~(RE_CONTEXT_INVALID_DUP | RE_DOT_NOT_NULL))
+
+# define RE_SYNTAX_EGREP						\
+  ((RE_SYNTAX_POSIX_EXTENDED | RE_INVALID_INTERVAL_ORD | RE_NEWLINE_ALT) \
+   & ~(RE_CONTEXT_INVALID_OPS | RE_DOT_NOT_NULL))
+
+/* POSIX grep -E behavior is no longer incompatible with GNU.  */
+# define RE_SYNTAX_POSIX_EGREP						\
+  RE_SYNTAX_EGREP
+
+/* P1003.2/D11.2, section 4.20.7.1, lines 5078ff.  */
+# define RE_SYNTAX_ED RE_SYNTAX_POSIX_BASIC
+
+# define RE_SYNTAX_SED RE_SYNTAX_POSIX_BASIC
+
+/* Syntax bits common to both basic and extended POSIX regex syntax.  */
+# define _RE_SYNTAX_POSIX_COMMON					\
+  (RE_CHAR_CLASSES | RE_DOT_NEWLINE      | RE_DOT_NOT_NULL		\
+   | RE_INTERVALS  | RE_NO_EMPTY_RANGES)
+
+# define RE_SYNTAX_POSIX_BASIC						\
+  (_RE_SYNTAX_POSIX_COMMON | RE_BK_PLUS_QM | RE_CONTEXT_INVALID_DUP)
+
+/* Differs from ..._POSIX_BASIC only in that RE_BK_PLUS_QM becomes
+   RE_LIMITED_OPS, i.e., \? \+ \| are not recognized.  Actually, this
+   isn't minimal, since other operators, such as \`, aren't disabled.  */
+# define RE_SYNTAX_POSIX_MINIMAL_BASIC					\
+  (_RE_SYNTAX_POSIX_COMMON | RE_LIMITED_OPS)
+
+# define RE_SYNTAX_POSIX_EXTENDED					\
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INDEP_OPS   | RE_NO_BK_BRACES				\
+   | RE_NO_BK_PARENS        | RE_NO_BK_VBAR				\
+   | RE_CONTEXT_INVALID_OPS | RE_UNMATCHED_RIGHT_PAREN_ORD)
+
+/* Differs from ..._POSIX_EXTENDED in that RE_CONTEXT_INDEP_OPS is
+   removed and RE_NO_BK_REFS is added.  */
+# define RE_SYNTAX_POSIX_MINIMAL_EXTENDED				\
+  (_RE_SYNTAX_POSIX_COMMON  | RE_CONTEXT_INDEP_ANCHORS			\
+   | RE_CONTEXT_INVALID_OPS | RE_NO_BK_BRACES				\
+   | RE_NO_BK_PARENS        | RE_NO_BK_REFS				\
+   | RE_NO_BK_VBAR	    | RE_UNMATCHED_RIGHT_PAREN_ORD)
+/* [[[end syntaxes]]] */
+
+
+/* RE_DUP_MAX is 2**15 - 1 because an earlier implementation stored
+   the counter as a 2-byte signed integer.  This is no longer true, so
+   RE_DUP_MAX could be increased to (INT_MAX / 10 - 1), or to
+   ((SIZE_MAX - 9) / 10) if _REGEX_LARGE_OFFSETS is defined.
+   However, there would be a huge performance problem if someone
+   actually used a pattern like a\{214748363\}, so RE_DUP_MAX retains
+   its historical value.  */
+# define RE_DUP_MAX (0x7fff)
+
+
+
+/* POSIX 'cflags' bits (i.e., information for 'regcomp').  */
+
+/* If this bit is set, then use extended regular expression syntax.
+   If not set, then use basic regular expression syntax.  */
+#define REG_EXTENDED 1
+
+/* If this bit is set, then ignore case when matching.
+   If not set, then case is significant.  */
+#define REG_ICASE (1 << 1)
+
+/* If this bit is set, then anchors do not match at newline
+     characters in the string.
+   If not set, then anchors do match at newlines.  */
+#define REG_NEWLINE (1 << 2)
+
+/* If this bit is set, then report only success or fail in regexec.
+   If not set, then returns differ between not matching and errors.  */
+#define REG_NOSUB (1 << 3)
+
+
+/* POSIX 'eflags' bits (i.e., information for regexec).  */
+
+/* If this bit is set, then the beginning-of-line operator doesn't match
+     the beginning of the string (presumably because it's not the
+     beginning of a line).
+   If not set, then the beginning-of-line operator does match the
+     beginning of the string.  */
+#define REG_NOTBOL 1
+
+/* Like REG_NOTBOL, except for the end-of-line.  */
+#define REG_NOTEOL (1 << 1)
+
+/* Use PMATCH[0] to delimit the start and end of the search in the
+   buffer.  */
+#define REG_STARTEND (1 << 2)
+
+
+/* If any error codes are removed, changed, or added, update the
+   '__re_error_msgid' table in regcomp.c.  */
+
+typedef enum
+{
+  _REG_ENOSYS = -1,	/* This will never happen for this implementation.  */
+  _REG_NOERROR = 0,	/* Success.  */
+  _REG_NOMATCH,		/* Didn't find a match (for regexec).  */
+
+  /* POSIX regcomp return error codes.  (In the order listed in the
+     standard.)  */
+  _REG_BADPAT,		/* Invalid pattern.  */
+  _REG_ECOLLATE,	/* Invalid collating element.  */
+  _REG_ECTYPE,		/* Invalid character class name.  */
+  _REG_EESCAPE,		/* Trailing backslash.  */
+  _REG_ESUBREG,		/* Invalid back reference.  */
+  _REG_EBRACK,		/* Unmatched left bracket.  */
+  _REG_EPAREN,		/* Parenthesis imbalance.  */
+  _REG_EBRACE,		/* Unmatched \{.  */
+  _REG_BADBR,		/* Invalid contents of \{\}.  */
+  _REG_ERANGE,		/* Invalid range end.  */
+  _REG_ESPACE,		/* Ran out of memory.  */
+  _REG_BADRPT,		/* No preceding re for repetition op.  */
+
+  /* Error codes we've added.  */
+  _REG_EEND,		/* Premature end.  */
+  _REG_ESIZE,		/* Too large (e.g., repeat count too large).  */
+  _REG_ERPAREN		/* Unmatched ) or \); not returned from regcomp.  */
+} reg_errcode_t;
+
+#if defined _XOPEN_SOURCE || defined __USE_XOPEN2K
+# define REG_ENOSYS	_REG_ENOSYS
+#endif
+#define REG_NOERROR	_REG_NOERROR
+#define REG_NOMATCH	_REG_NOMATCH
+#define REG_BADPAT	_REG_BADPAT
+#define REG_ECOLLATE	_REG_ECOLLATE
+#define REG_ECTYPE	_REG_ECTYPE
+#define REG_EESCAPE	_REG_EESCAPE
+#define REG_ESUBREG	_REG_ESUBREG
+#define REG_EBRACK	_REG_EBRACK
+#define REG_EPAREN	_REG_EPAREN
+#define REG_EBRACE	_REG_EBRACE
+#define REG_BADBR	_REG_BADBR
+#define REG_ERANGE	_REG_ERANGE
+#define REG_ESPACE	_REG_ESPACE
+#define REG_BADRPT	_REG_BADRPT
+#define REG_EEND	_REG_EEND
+#define REG_ESIZE	_REG_ESIZE
+#define REG_ERPAREN	_REG_ERPAREN
+
+/* This data structure represents a compiled pattern.  Before calling
+   the pattern compiler, the fields 'buffer', 'allocated', 'fastmap',
+   and 'translate' can be set.  After the pattern has been compiled,
+   the fields 're_nsub', 'not_bol' and 'not_eol' are available.  All
+   other fields are private to the regex routines.  */
+
+#ifndef RE_TRANSLATE_TYPE
+# define __RE_TRANSLATE_TYPE unsigned char *
+
+#  define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE
+
+#endif
+
+# define __REPB_PREFIX(name) name
+
+struct re_pattern_buffer
+{
+  /* Space that holds the compiled pattern.  The type
+     'struct re_dfa_t' is private and is not declared here.  */
+  struct re_dfa_t *__REPB_PREFIX(buffer);
+
+  /* Number of bytes to which 'buffer' points.  */
+  __re_long_size_t __REPB_PREFIX(allocated);
+
+  /* Number of bytes actually used in 'buffer'.  */
+  __re_long_size_t __REPB_PREFIX(used);
+
+  /* Syntax setting with which the pattern was compiled.  */
+  reg_syntax_t __REPB_PREFIX(syntax);
+
+  /* Pointer to a fastmap, if any, otherwise zero.  re_search uses the
+     fastmap, if there is one, to skip over impossible starting points
+     for matches.  */
+  char *__REPB_PREFIX(fastmap);
+
+  /* Either a translate table to apply to all characters before
+     comparing them, or zero for no translation.  The translation is
+     applied to a pattern when it is compiled and to a string when it
+     is matched.  */
+  __RE_TRANSLATE_TYPE __REPB_PREFIX(translate);
+
+  /* Number of subexpressions found by the compiler.  */
+  size_t re_nsub;
+
+  /* Zero if this pattern cannot match the empty string, one else.
+     Well, in truth it's used only in 're_search_2', to see whether or
+     not we should use the fastmap, so we don't set this absolutely
+     perfectly; see 're_compile_fastmap' (the "duplicate" case).  */
+  unsigned __REPB_PREFIX(can_be_null) : 1;
+
+  /* If REGS_UNALLOCATED, allocate space in the 'regs' structure
+     for 'max (RE_NREGS, re_nsub + 1)' groups.
+     If REGS_REALLOCATE, reallocate space if necessary.
+     If REGS_FIXED, use what's there.  */
+
+# define REGS_UNALLOCATED 0
+# define REGS_REALLOCATE 1
+# define REGS_FIXED 2
+
+  unsigned __REPB_PREFIX(regs_allocated) : 2;
+
+  /* Set to zero when 're_compile_pattern' compiles a pattern; set to
+     one by 're_compile_fastmap' if it updates the fastmap.  */
+  unsigned __REPB_PREFIX(fastmap_accurate) : 1;
+
+  /* If set, 're_match_2' does not return information about
+     subexpressions.  */
+  unsigned __REPB_PREFIX(no_sub) : 1;
+
+  /* If set, a beginning-of-line anchor doesn't match at the beginning
+     of the string.  */
+  unsigned __REPB_PREFIX(not_bol) : 1;
+
+  /* Similarly for an end-of-line anchor.  */
+  unsigned __REPB_PREFIX(not_eol) : 1;
+
+  /* If true, an anchor at a newline matches.  */
+  unsigned __REPB_PREFIX(newline_anchor) : 1;
+};
+
+typedef struct re_pattern_buffer regex_t;
+
+/* Type for byte offsets within the string.  POSIX mandates this.  */
+#ifdef _REGEX_LARGE_OFFSETS
+/* POSIX 1003.1-2008 requires that regoff_t be at least as wide as
+   ptrdiff_t and ssize_t.  We don't know of any hosts where ptrdiff_t
+   is wider than ssize_t, so ssize_t is safe.  ptrdiff_t is not
+   visible here, so use ssize_t.  */
+typedef ssize_t regoff_t;
+#else
+/* The traditional GNU regex implementation mishandles strings longer
+   than INT_MAX.  */
+typedef int regoff_t;
+#endif
+
+
+
+/* This is the structure we store register match data in.  See
+   regex.texinfo for a full description of what registers match.  */
+struct re_registers
+{
+  __re_size_t num_regs;
+  regoff_t *start;
+  regoff_t *end;
+};
+
+
+/* If 'regs_allocated' is REGS_UNALLOCATED in the pattern buffer,
+   're_match_2' returns information about at least this many registers
+   the first time a 'regs' structure is passed.  */
+# ifndef RE_NREGS
+#  define RE_NREGS 30
+# endif
+
+
+
+/* POSIX specification for registers.  Aside from the different names than
+   're_registers', POSIX uses an array of structures, instead of a
+   structure of arrays.  */
+typedef struct
+{
+  regoff_t rm_so;  /* Byte offset from string's start to substring's start.  */
+  regoff_t rm_eo;  /* Byte offset from string's start to substring's end.  */
+} regmatch_t;
+
+/* Declarations for routines.  */
+
+
+/* Sets the current default syntax to SYNTAX, and return the old syntax.
+   You can also simply assign to the 're_syntax_options' variable.  */
+extern reg_syntax_t re_set_syntax (reg_syntax_t __syntax);
+
+/* Compile the regular expression PATTERN, with length LENGTH
+   and syntax given by the global 're_syntax_options', into the buffer
+   BUFFER.  Return NULL if successful, and an error string if not.
+
+   To free the allocated storage, you must call 'regfree' on BUFFER.
+   Note that the translate table must either have been initialized by
+   'regcomp', with a malloc'ed value, or set to NULL before calling
+   'regfree'.  */
+extern const char *re_compile_pattern (const char *__pattern, size_t __length,
+				       struct re_pattern_buffer *__buffer);
+
+
+/* Compile a fastmap for the compiled pattern in BUFFER; used to
+   accelerate searches.  Return 0 if successful and -2 if was an
+   internal error.  */
+extern int re_compile_fastmap (struct re_pattern_buffer *__buffer);
+
+
+/* Search in the string STRING (with length LENGTH) for the pattern
+   compiled into BUFFER.  Start searching at position START, for RANGE
+   characters.  Return the starting position of the match, -1 for no
+   match, or -2 for an internal error.  Also return register
+   information in REGS (if REGS and BUFFER->no_sub are nonzero).  */
+extern regoff_t re_search (struct re_pattern_buffer *__buffer,
+			   const char *__String, regoff_t __length,
+			   regoff_t __start, regoff_t __range,
+			   struct re_registers *__regs);
+
+
+/* Like 're_search', but search in the concatenation of STRING1 and
+   STRING2.  Also, stop searching at index START + STOP.  */
+extern regoff_t re_search_2 (struct re_pattern_buffer *__buffer,
+			     const char *__string1, regoff_t __length1,
+			     const char *__string2, regoff_t __length2,
+			     regoff_t __start, regoff_t __range,
+			     struct re_registers *__regs,
+			     regoff_t __stop);
+
+
+/* Like 're_search', but return how many characters in STRING the regexp
+   in BUFFER matched, starting at position START.  */
+extern regoff_t re_match (struct re_pattern_buffer *__buffer,
+			  const char *__String, regoff_t __length,
+			  regoff_t __start, struct re_registers *__regs);
+
+
+/* Relates to 're_match' as 're_search_2' relates to 're_search'.  */
+extern regoff_t re_match_2 (struct re_pattern_buffer *__buffer,
+			    const char *__string1, regoff_t __length1,
+			    const char *__string2, regoff_t __length2,
+			    regoff_t __start, struct re_registers *__regs,
+			    regoff_t __stop);
+
+
+/* Set REGS to hold NUM_REGS registers, storing them in STARTS and
+   ENDS.  Subsequent matches using BUFFER and REGS will use this memory
+   for recording register information.  STARTS and ENDS must be
+   allocated with malloc, and must each be at least 'NUM_REGS * sizeof
+   (regoff_t)' bytes long.
+
+   If NUM_REGS == 0, then subsequent matches should allocate their own
+   register data.
+
+   Unless this function is called, the first search or match using
+   BUFFER will allocate its own register data, without
+   freeing the old data.  */
+extern void re_set_registers (struct re_pattern_buffer *__buffer,
+			      struct re_registers *__regs,
+			      __re_size_t __num_regs,
+			      regoff_t *__starts, regoff_t *__ends);
+
+/* For plain 'restrict', use glibc's __restrict if defined.
+   Otherwise, GCC 2.95 and later have "__restrict"; C99 compilers have
+   "restrict", and "configure" may have defined "restrict".
+   Other compilers use __restrict, __restrict__, and _Restrict, and
+   'configure' might #define 'restrict' to those words, so pick a
+   different name.  */
+#ifndef _Restrict_
+# if defined __restrict || 2 < __GNUC__ + (95 <= __GNUC_MINOR__)
+#  define _Restrict_ __restrict
+# elif 199901L <= __STDC_VERSION__ || defined restrict
+#  define _Restrict_ restrict
+# else
+#  define _Restrict_
+# endif
+#endif
+/* For [restrict], use glibc's __restrict_arr if available.
+   Otherwise, GCC 3.1 (not in C++ mode) and C99 support [restrict].  */
+#ifndef _Restrict_arr_
+# ifdef __restrict_arr
+#  define _Restrict_arr_ __restrict_arr
+# elif ((199901L <= __STDC_VERSION__ || 3 < __GNUC__ + (1 <= __GNUC_MINOR__)) \
+        && !defined __GNUG__)
+#  define _Restrict_arr_ _Restrict_
+# else
+#  define _Restrict_arr_
+# endif
+#endif
+
+/* POSIX compatibility.  */
+extern int regcomp (regex_t *_Restrict_ __preg,
+		    const char *_Restrict_ __pattern,
+		    int __cflags);
+
+extern int regexec (const regex_t *_Restrict_ __preg,
+		    const char *_Restrict_ __String, size_t __nmatch,
+		    regmatch_t __pmatch[_Restrict_arr_],
+		    int __eflags);
+
+extern size_t regerror (int __errcode, const regex_t *_Restrict_ __preg,
+			char *_Restrict_ __errbuf, size_t __errbuf_size);
+
+extern void regfree (regex_t *__preg);
+
+
+#ifdef __cplusplus
+}
+#endif	/* C++ */
+
+#endif /* regex.h */
diff --git a/headers-mingw/regex_internal.h b/headers-mingw/regex_internal.h
new file mode 100644
index 0000000..b4ae872
--- /dev/null
+++ b/headers-mingw/regex_internal.h
@@ -0,0 +1,780 @@
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef _REGEX_INTERNAL_H
+#define _REGEX_INTERNAL_H 1
+
+#include <assert.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "langinfo.h"
+#include <locale.h>
+#include <wchar.h>
+#include <wctype.h>
+#include <stdbool.h>
+#include <stdint.h>
+
+#include "intprops.h"
+
+#ifdef _LIBC
+# include <libc-lock.h>
+# define lock_define(name) __libc_lock_define (, name)
+# define lock_init(lock) (__libc_lock_init (lock), 0)
+# define lock_fini(lock) ((void) 0)
+# define lock_lock(lock) __libc_lock_lock (lock)
+# define lock_unlock(lock) __libc_lock_unlock (lock)
+#elif defined GNULIB_LOCK && !defined USE_UNLOCKED_IO
+# include "glthread/lock.h"
+  /* Use gl_lock_define if empty macro arguments are known to work.
+     Otherwise, fall back on less-portable substitutes.  */
+# if ((defined __GNUC__ && !defined __STRICT_ANSI__) \
+      || (defined __STDC_VERSION__ && 199901L <= __STDC_VERSION__))
+#  define lock_define(name) gl_lock_define (, name)
+# elif USE_POSIX_THREADS
+#  define lock_define(name) pthread_mutex_t name;
+# elif USE_PTH_THREADS
+#  define lock_define(name) pth_mutex_t name;
+# elif USE_SOLARIS_THREADS
+#  define lock_define(name) mutex_t name;
+# elif USE_WINDOWS_THREADS
+#  define lock_define(name) gl_lock_t name;
+# else
+#  define lock_define(name)
+# endif
+# define lock_init(lock) glthread_lock_init (&(lock))
+# define lock_fini(lock) glthread_lock_destroy (&(lock))
+# define lock_lock(lock) glthread_lock_lock (&(lock))
+# define lock_unlock(lock) glthread_lock_unlock (&(lock))
+#elif defined GNULIB_PTHREAD && !defined USE_UNLOCKED_IO
+# include <pthread.h>
+# define lock_define(name) pthread_mutex_t name;
+# define lock_init(lock) pthread_mutex_init (&(lock), 0)
+# define lock_fini(lock) pthread_mutex_destroy (&(lock))
+# define lock_lock(lock) pthread_mutex_lock (&(lock))
+# define lock_unlock(lock) pthread_mutex_unlock (&(lock))
+#else
+# define lock_define(name)
+# define lock_init(lock) 0
+# define lock_fini(lock) ((void) 0)
+  /* The 'dfa' avoids an "unused variable 'dfa'" warning from GCC.  */
+# define lock_lock(lock) ((void) dfa)
+# define lock_unlock(lock) ((void) 0)
+#endif
+
+/* In case that the system doesn't have isblank().  */
+#if !defined _LIBC && ! (defined isblank || (HAVE_ISBLANK && HAVE_DECL_ISBLANK))
+# define isblank(ch) ((ch) == ' ' || (ch) == '\t')
+#endif
+
+
+# undef gettext
+# define gettext(msgid) (msgid)
+
+
+#ifndef gettext_noop
+/* This define is so xgettext can find the internationalizable
+   strings.  */
+# define gettext_noop(String) String
+#endif
+
+/* Number of ASCII characters.  */
+#define ASCII_CHARS 0x80
+
+/* Number of single byte characters.  */
+#define SBC_MAX (UCHAR_MAX + 1)
+
+#define COLL_ELEM_LEN_MAX 8
+
+/* The character which represents newline.  */
+#define NEWLINE_CHAR '\n'
+#define WIDE_NEWLINE_CHAR L'\n'
+
+/* Rename to standard API for using out of glibc.  */
+#ifndef _LIBC
+# undef __wctype
+# undef __iswalnum
+# undef __iswctype
+# undef __towlower
+# undef __towupper
+# define __wctype wctype
+# define __iswalnum iswalnum
+# define __iswctype iswctype
+# define __towlower towlower
+# define __towupper towupper
+# define __btowc btowc
+# define __mbrtowc mbrtowc
+# define __wcrtomb wcrtomb
+# define __regfree regfree
+# define attribute_hidden
+#endif /* not _LIBC */
+
+#if __GNUC__ < 3 + (__GNUC_MINOR__ < 1)
+# define __attribute__(arg)
+#endif
+
+#ifndef SSIZE_MAX
+# define SSIZE_MAX ((ssize_t) (SIZE_MAX / 2))
+#endif
+
+/* The type of indexes into strings.  This is signed, not size_t,
+   since the API requires indexes to fit in regoff_t anyway, and using
+   signed integers makes the code a bit smaller and presumably faster.
+   The traditional GNU regex implementation uses int for indexes.
+   The POSIX-compatible implementation uses a possibly-wider type.
+   The name 'Idx' is three letters to minimize the hassle of
+   reindenting a lot of regex code that formerly used 'int'.  */
+typedef regoff_t Idx;
+#ifdef _REGEX_LARGE_OFFSETS
+# define IDX_MAX SSIZE_MAX
+#else
+# define IDX_MAX INT_MAX
+#endif
+
+#ifdef _REGEX_LARGE_OFFSETS
+
+/* Use types and values that are wide enough to represent signed and
+   unsigned byte offsets in memory.  This currently works only when
+   the regex code is used outside of the GNU C library; it is not yet
+   supported within glibc itself, and glibc users should not define
+   _REGEX_LARGE_OFFSETS.  */
+
+/* The type of object sizes.  */
+typedef size_t __re_size_t;
+
+/* The type of object sizes, in places where the traditional code
+   uses unsigned long int.  */
+typedef size_t __re_long_size_t;
+
+#else
+
+/* The traditional GNU regex implementation mishandles strings longer
+   than INT_MAX.  */
+typedef unsigned int __re_size_t;
+typedef unsigned long int __re_long_size_t;
+
+#endif
+
+#ifndef RE_TRANSLATE_TYPE
+# define __RE_TRANSLATE_TYPE unsigned char *
+#  define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE
+#endif
+
+/* The following bits are used to determine the regexp syntax we
+   recognize.  The set/not-set meanings are chosen so that Emacs syntax
+   remains the value 0.  The bits are given in alphabetical order, and
+   the definitions shifted by one from the previous bit; thus, when we
+   add or remove a bit, only one other definition need change.  */
+typedef unsigned long int reg_syntax_t;
+
+/* A hash value, suitable for computing hash tables.  */
+typedef __re_size_t re_hashval_t;
+
+/* An integer used to represent a set of bits.  It must be unsigned,
+   and must be at least as wide as unsigned int.  */
+typedef unsigned long int bitset_word_t;
+/* All bits set in a bitset_word_t.  */
+#define BITSET_WORD_MAX ULONG_MAX
+
+/* Number of bits in a bitset_word_t.  For portability to hosts with
+   padding bits, do not use '(sizeof (bitset_word_t) * CHAR_BIT)';
+   instead, deduce it directly from BITSET_WORD_MAX.  Avoid
+   greater-than-32-bit integers and unconditional shifts by more than
+   31 bits, as they're not portable.  */
+#if BITSET_WORD_MAX == 0xffffffffUL
+# define BITSET_WORD_BITS 32
+#elif BITSET_WORD_MAX >> 31 >> 4 == 1
+# define BITSET_WORD_BITS 36
+#elif BITSET_WORD_MAX >> 31 >> 16 == 1
+# define BITSET_WORD_BITS 48
+#elif BITSET_WORD_MAX >> 31 >> 28 == 1
+# define BITSET_WORD_BITS 60
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 1 == 1
+# define BITSET_WORD_BITS 64
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 9 == 1
+# define BITSET_WORD_BITS 72
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 3 == 1
+# define BITSET_WORD_BITS 128
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 == 1
+# define BITSET_WORD_BITS 256
+#elif BITSET_WORD_MAX >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 31 >> 7 > 1
+# define BITSET_WORD_BITS 257 /* any value > SBC_MAX will do here */
+# if BITSET_WORD_BITS <= SBC_MAX
+#  error "Invalid SBC_MAX"
+# endif
+#else
+# error "Add case for new bitset_word_t size"
+#endif
+
+/* Number of bitset_word_t values in a bitset_t.  */
+#define BITSET_WORDS ((SBC_MAX + BITSET_WORD_BITS - 1) / BITSET_WORD_BITS)
+
+typedef bitset_word_t bitset_t[BITSET_WORDS];
+typedef bitset_word_t *re_bitset_ptr_t;
+typedef const bitset_word_t *re_const_bitset_ptr_t;
+
+#define PREV_WORD_CONSTRAINT 0x0001
+#define PREV_NOTWORD_CONSTRAINT 0x0002
+#define NEXT_WORD_CONSTRAINT 0x0004
+#define NEXT_NOTWORD_CONSTRAINT 0x0008
+#define PREV_NEWLINE_CONSTRAINT 0x0010
+#define NEXT_NEWLINE_CONSTRAINT 0x0020
+#define PREV_BEGBUF_CONSTRAINT 0x0040
+#define NEXT_ENDBUF_CONSTRAINT 0x0080
+#define WORD_DELIM_CONSTRAINT 0x0100
+#define NOT_WORD_DELIM_CONSTRAINT 0x0200
+
+typedef enum
+{
+  INSIDE_WORD = PREV_WORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_FIRST = PREV_NOTWORD_CONSTRAINT | NEXT_WORD_CONSTRAINT,
+  WORD_LAST = PREV_WORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  INSIDE_NOTWORD = PREV_NOTWORD_CONSTRAINT | NEXT_NOTWORD_CONSTRAINT,
+  LINE_FIRST = PREV_NEWLINE_CONSTRAINT,
+  LINE_LAST = NEXT_NEWLINE_CONSTRAINT,
+  BUF_FIRST = PREV_BEGBUF_CONSTRAINT,
+  BUF_LAST = NEXT_ENDBUF_CONSTRAINT,
+  WORD_DELIM = WORD_DELIM_CONSTRAINT,
+  NOT_WORD_DELIM = NOT_WORD_DELIM_CONSTRAINT
+} re_context_type;
+
+typedef struct
+{
+  Idx alloc;
+  Idx nelem;
+  Idx *elems;
+} re_node_set;
+
+typedef enum
+{
+  NON_TYPE = 0,
+
+  /* Node type, These are used by token, node, tree.  */
+  CHARACTER = 1,
+  END_OF_RE = 2,
+  SIMPLE_BRACKET = 3,
+  OP_BACK_REF = 4,
+  OP_PERIOD = 5,
+
+  /* We define EPSILON_BIT as a macro so that OP_OPEN_SUBEXP is used
+     when the debugger shows values of this enum type.  */
+#define EPSILON_BIT 8
+  OP_OPEN_SUBEXP = EPSILON_BIT | 0,
+  OP_CLOSE_SUBEXP = EPSILON_BIT | 1,
+  OP_ALT = EPSILON_BIT | 2,
+  OP_DUP_ASTERISK = EPSILON_BIT | 3,
+  ANCHOR = EPSILON_BIT | 4,
+
+  /* Tree type, these are used only by tree. */
+  CONCAT = 16,
+  SUBEXP = 17,
+
+  /* Token type, these are used only by token.  */
+  OP_DUP_PLUS = 18,
+  OP_DUP_QUESTION,
+  OP_OPEN_BRACKET,
+  OP_CLOSE_BRACKET,
+  OP_CHARSET_RANGE,
+  OP_OPEN_DUP_NUM,
+  OP_CLOSE_DUP_NUM,
+  OP_NON_MATCH_LIST,
+  OP_OPEN_COLL_ELEM,
+  OP_CLOSE_COLL_ELEM,
+  OP_OPEN_EQUIV_CLASS,
+  OP_CLOSE_EQUIV_CLASS,
+  OP_OPEN_CHAR_CLASS,
+  OP_CLOSE_CHAR_CLASS,
+  OP_WORD,
+  OP_NOTWORD,
+  OP_SPACE,
+  OP_NOTSPACE,
+  BACK_SLASH
+
+} re_token_type_t;
+
+typedef struct
+{
+  union
+  {
+    unsigned char c;		/* for CHARACTER */
+    re_bitset_ptr_t sbcset;	/* for SIMPLE_BRACKET */
+    Idx idx;			/* for BACK_REF */
+    re_context_type ctx_type;	/* for ANCHOR */
+  } opr;
+#if __GNUC__ >= 2 && !defined __STRICT_ANSI__
+  re_token_type_t type : 8;
+#else
+  re_token_type_t type;
+#endif
+  unsigned int constraint : 10;	/* context constraint */
+  unsigned int duplicated : 1;
+  unsigned int opt_subexp : 1;
+  unsigned int word_char : 1;
+} re_token_t;
+
+#define IS_EPSILON_NODE(type) ((type) & EPSILON_BIT)
+
+struct re_string_t
+{
+  /* Indicate the raw buffer which is the original string passed as an
+     argument of regexec(), re_search(), etc..  */
+  const unsigned char *raw_mbs;
+  /* Store the multibyte string.  In case of "case insensitive mode" like
+     REG_ICASE, upper cases of the string are stored, otherwise MBS points
+     the same address that RAW_MBS points.  */
+  unsigned char *mbs;
+  /* Index in RAW_MBS.  Each character mbs[i] corresponds to
+     raw_mbs[raw_mbs_idx + i].  */
+  Idx raw_mbs_idx;
+  /* The length of the valid characters in the buffers.  */
+  Idx valid_len;
+  /* The corresponding number of bytes in raw_mbs array.  */
+  Idx valid_raw_len;
+  /* The length of the buffers MBS and WCS.  */
+  Idx bufs_len;
+  /* The index in MBS, which is updated by re_string_fetch_byte.  */
+  Idx cur_idx;
+  /* length of RAW_MBS array.  */
+  Idx raw_len;
+  /* This is RAW_LEN - RAW_MBS_IDX + VALID_LEN - VALID_RAW_LEN.  */
+  Idx len;
+  /* End of the buffer may be shorter than its length in the cases such
+     as re_match_2, re_search_2.  Then, we use STOP for end of the buffer
+     instead of LEN.  */
+  Idx raw_stop;
+  /* This is RAW_STOP - RAW_MBS_IDX adjusted through OFFSETS.  */
+  Idx stop;
+
+  /* The context of mbs[0].  We store the context independently, since
+     the context of mbs[0] may be different from raw_mbs[0], which is
+     the beginning of the input string.  */
+  unsigned int tip_context;
+  /* The translation passed as a part of an argument of re_compile_pattern.  */
+  RE_TRANSLATE_TYPE trans;
+  /* Copy of re_dfa_t's word_char.  */
+  re_const_bitset_ptr_t word_char;
+  /* true if REG_ICASE.  */
+  unsigned char icase;
+  unsigned char is_utf8;
+  unsigned char map_notascii;
+  unsigned char mbs_allocated;
+  unsigned char offsets_needed;
+  unsigned char newline_anchor;
+  unsigned char word_ops_used;
+  int mb_cur_max;
+};
+typedef struct re_string_t re_string_t;
+
+
+struct re_dfa_t;
+typedef struct re_dfa_t re_dfa_t;
+
+# define IS_IN(libc) false
+
+
+#define re_string_peek_byte(pstr, offset) \
+  ((pstr)->mbs[(pstr)->cur_idx + offset])
+#define re_string_fetch_byte(pstr) \
+  ((pstr)->mbs[(pstr)->cur_idx++])
+#define re_string_first_byte(pstr, idx) \
+  ((idx) == (pstr)->valid_len || (pstr)->wcs[idx] != WEOF)
+#define re_string_is_single_byte_char(pstr, idx) \
+  ((pstr)->wcs[idx] != WEOF && ((pstr)->valid_len == (idx) + 1 \
+				|| (pstr)->wcs[(idx) + 1] != WEOF))
+#define re_string_eoi(pstr) ((pstr)->stop <= (pstr)->cur_idx)
+#define re_string_cur_idx(pstr) ((pstr)->cur_idx)
+#define re_string_get_buffer(pstr) ((pstr)->mbs)
+#define re_string_length(pstr) ((pstr)->len)
+#define re_string_byte_at(pstr,idx) ((pstr)->mbs[idx])
+#define re_string_skip_bytes(pstr,idx) ((pstr)->cur_idx += (idx))
+#define re_string_set_index(pstr,idx) ((pstr)->cur_idx = (idx))
+
+#if HAVE_ALLOCA
+# include <alloca.h>
+#endif
+
+# if HAVE_ALLOCA
+/* The OS usually guarantees only one guard page at the bottom of the stack,
+   and a page size can be as small as 4096 bytes.  So we cannot safely
+   allocate anything larger than 4096 bytes.  Also care for the possibility
+   of a few compiler-allocated temporary stack slots.  */
+#  define __libc_use_alloca(n) ((n) < 4032)
+# else
+/* alloca is implemented with malloc, so just use malloc.  */
+#  define __libc_use_alloca(n) 0
+#  undef alloca
+#  define alloca(n) malloc (n)
+# endif
+
+
+#if !defined MALLOC_0_IS_NONNULL
+# define MALLOC_0_IS_NONNULL 0
+#endif
+
+#ifndef MAX
+# define MAX(a,b) ((a) < (b) ? (b) : (a))
+#endif
+#ifndef MIN
+# define MIN(a,b) ((a) < (b) ? (a) : (b))
+#endif
+
+#define re_malloc(t,n) ((t *) malloc ((n) * sizeof (t)))
+#define re_realloc(p,t,n) ((t *) realloc (p, (n) * sizeof (t)))
+#define re_free(p) free (p)
+
+struct bin_tree_t
+{
+  struct bin_tree_t *parent;
+  struct bin_tree_t *left;
+  struct bin_tree_t *right;
+  struct bin_tree_t *first;
+  struct bin_tree_t *next;
+
+  re_token_t token;
+
+  /* 'node_idx' is the index in dfa->nodes, if 'type' == 0.
+     Otherwise 'type' indicate the type of this node.  */
+  Idx node_idx;
+};
+typedef struct bin_tree_t bin_tree_t;
+
+#define BIN_TREE_STORAGE_SIZE \
+  ((1024 - sizeof (void *)) / sizeof (bin_tree_t))
+
+struct bin_tree_storage_t
+{
+  struct bin_tree_storage_t *next;
+  bin_tree_t data[BIN_TREE_STORAGE_SIZE];
+};
+typedef struct bin_tree_storage_t bin_tree_storage_t;
+
+#define CONTEXT_WORD 1
+#define CONTEXT_NEWLINE (CONTEXT_WORD << 1)
+#define CONTEXT_BEGBUF (CONTEXT_NEWLINE << 1)
+#define CONTEXT_ENDBUF (CONTEXT_BEGBUF << 1)
+
+#define IS_WORD_CONTEXT(c) ((c) & CONTEXT_WORD)
+#define IS_NEWLINE_CONTEXT(c) ((c) & CONTEXT_NEWLINE)
+#define IS_BEGBUF_CONTEXT(c) ((c) & CONTEXT_BEGBUF)
+#define IS_ENDBUF_CONTEXT(c) ((c) & CONTEXT_ENDBUF)
+#define IS_ORDINARY_CONTEXT(c) ((c) == 0)
+
+#define IS_WORD_CHAR(ch) (isalnum (ch) || (ch) == '_')
+#define IS_NEWLINE(ch) ((ch) == NEWLINE_CHAR)
+#define IS_WIDE_WORD_CHAR(ch) (__iswalnum (ch) || (ch) == L'_')
+#define IS_WIDE_NEWLINE(ch) ((ch) == WIDE_NEWLINE_CHAR)
+
+#define NOT_SATISFY_PREV_CONSTRAINT(constraint,context) \
+ ((((constraint) & PREV_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || ((constraint & PREV_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context))\
+  || ((constraint & PREV_BEGBUF_CONSTRAINT) && !IS_BEGBUF_CONTEXT (context)))
+
+#define NOT_SATISFY_NEXT_CONSTRAINT(constraint,context) \
+ ((((constraint) & NEXT_WORD_CONSTRAINT) && !IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NOTWORD_CONSTRAINT) && IS_WORD_CONTEXT (context)) \
+  || (((constraint) & NEXT_NEWLINE_CONSTRAINT) && !IS_NEWLINE_CONTEXT (context)) \
+  || (((constraint) & NEXT_ENDBUF_CONSTRAINT) && !IS_ENDBUF_CONTEXT (context)))
+
+struct re_dfastate_t
+{
+  re_hashval_t hash;
+  re_node_set nodes;
+  re_node_set non_eps_nodes;
+  re_node_set inveclosure;
+  re_node_set *entrance_nodes;
+  struct re_dfastate_t **trtable, **word_trtable;
+  unsigned int context : 4;
+  unsigned int halt : 1;
+  /* If this state can accept "multi byte".
+     Note that we refer to multibyte characters, and multi character
+     collating elements as "multi byte".  */
+  unsigned int accept_mb : 1;
+  /* If this state has backreference node(s).  */
+  unsigned int has_backref : 1;
+  unsigned int has_constraint : 1;
+};
+typedef struct re_dfastate_t re_dfastate_t;
+
+struct re_state_table_entry
+{
+  Idx num;
+  Idx alloc;
+  re_dfastate_t **array;
+};
+
+/* Array type used in re_sub_match_last_t and re_sub_match_top_t.  */
+
+typedef struct
+{
+  Idx next_idx;
+  Idx alloc;
+  re_dfastate_t **array;
+} state_array_t;
+
+/* Store information about the node NODE whose type is OP_CLOSE_SUBEXP.  */
+
+typedef struct
+{
+  Idx node;
+  Idx str_idx; /* The position NODE match at.  */
+  state_array_t path;
+} re_sub_match_last_t;
+
+/* Store information about the node NODE whose type is OP_OPEN_SUBEXP.
+   And information about the node, whose type is OP_CLOSE_SUBEXP,
+   corresponding to NODE is stored in LASTS.  */
+
+typedef struct
+{
+  Idx str_idx;
+  Idx node;
+  state_array_t *path;
+  Idx alasts; /* Allocation size of LASTS.  */
+  Idx nlasts; /* The number of LASTS.  */
+  re_sub_match_last_t **lasts;
+} re_sub_match_top_t;
+
+struct re_backref_cache_entry
+{
+  Idx node;
+  Idx str_idx;
+  Idx subexp_from;
+  Idx subexp_to;
+  char more;
+  char unused;
+  unsigned short int eps_reachable_subexps_map;
+};
+
+typedef struct
+{
+  /* The string object corresponding to the input string.  */
+  re_string_t input;
+  const re_dfa_t *dfa;
+  /* EFLAGS of the argument of regexec.  */
+  int eflags;
+  /* Where the matching ends.  */
+  Idx match_last;
+  Idx last_node;
+  /* The state log used by the matcher.  */
+  re_dfastate_t **state_log;
+  Idx state_log_top;
+  /* Back reference cache.  */
+  Idx nbkref_ents;
+  Idx abkref_ents;
+  struct re_backref_cache_entry *bkref_ents;
+  int max_mb_elem_len;
+  Idx nsub_tops;
+  Idx asub_tops;
+  re_sub_match_top_t **sub_tops;
+} re_match_context_t;
+
+typedef struct
+{
+  re_dfastate_t **sifted_states;
+  re_dfastate_t **limited_states;
+  Idx last_node;
+  Idx last_str_idx;
+  re_node_set limits;
+} re_sift_context_t;
+
+struct re_fail_stack_ent_t
+{
+  Idx idx;
+  Idx node;
+  regmatch_t *regs;
+  re_node_set eps_via_nodes;
+};
+
+struct re_fail_stack_t
+{
+  Idx num;
+  Idx alloc;
+  struct re_fail_stack_ent_t *stack;
+};
+
+struct re_dfa_t
+{
+  re_token_t *nodes;
+  size_t nodes_alloc;
+  size_t nodes_len;
+  Idx *nexts;
+  Idx *org_indices;
+  re_node_set *edests;
+  re_node_set *eclosures;
+  re_node_set *inveclosures;
+  struct re_state_table_entry *state_table;
+  re_dfastate_t *init_state;
+  re_dfastate_t *init_state_word;
+  re_dfastate_t *init_state_nl;
+  re_dfastate_t *init_state_begbuf;
+  bin_tree_t *str_tree;
+  bin_tree_storage_t *str_tree_storage;
+  re_bitset_ptr_t sb_char;
+  int str_tree_storage_idx;
+
+  /* number of subexpressions 're_nsub' is in regex_t.  */
+  re_hashval_t state_hash_mask;
+  Idx init_node;
+  Idx nbackref; /* The number of backreference in this dfa.  */
+
+  /* Bitmap expressing which backreference is used.  */
+  bitset_word_t used_bkref_map;
+  bitset_word_t completed_bkref_map;
+
+  unsigned int has_plural_match : 1;
+  /* If this dfa has "multibyte node", which is a backreference or
+     a node which can accept multibyte character or multi character
+     collating element.  */
+  unsigned int has_mb_node : 1;
+  unsigned int is_utf8 : 1;
+  unsigned int map_notascii : 1;
+  unsigned int word_ops_used : 1;
+  int mb_cur_max;
+  bitset_t word_char;
+  reg_syntax_t syntax;
+  Idx *subexp_map;
+  lock_define (lock)
+};
+
+#define re_node_set_init_empty(set) memset (set, '\0', sizeof (re_node_set))
+#define re_node_set_remove(set,id) \
+  (re_node_set_remove_at (set, re_node_set_contains (set, id) - 1))
+#define re_node_set_empty(p) ((p)->nelem = 0)
+#define re_node_set_free(set) re_free ((set)->elems)
+
+
+typedef enum
+{
+  SB_CHAR,
+  MB_CHAR,
+  EQUIV_CLASS,
+  COLL_SYM,
+  CHAR_CLASS
+} bracket_elem_type;
+
+typedef struct
+{
+  bracket_elem_type type;
+  union
+  {
+    unsigned char ch;
+    unsigned char *name;
+    wchar_t wch;
+  } opr;
+} bracket_elem_t;
+
+
+/* Functions for bitset_t operation.  */
+
+static inline void
+bitset_set (bitset_t set, Idx i)
+{
+  set[i / BITSET_WORD_BITS] |= (bitset_word_t) 1 << i % BITSET_WORD_BITS;
+}
+
+static inline void
+bitset_clear (bitset_t set, Idx i)
+{
+  set[i / BITSET_WORD_BITS] &= ~ ((bitset_word_t) 1 << i % BITSET_WORD_BITS);
+}
+
+static inline bool
+bitset_contain (const bitset_t set, Idx i)
+{
+  return (set[i / BITSET_WORD_BITS] >> i % BITSET_WORD_BITS) & 1;
+}
+
+static inline void
+bitset_empty (bitset_t set)
+{
+  memset (set, '\0', sizeof (bitset_t));
+}
+
+static inline void
+bitset_set_all (bitset_t set)
+{
+  memset (set, -1, sizeof (bitset_word_t) * (SBC_MAX / BITSET_WORD_BITS));
+  if (SBC_MAX % BITSET_WORD_BITS != 0)
+    set[BITSET_WORDS - 1] =
+      ((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1;
+}
+
+static inline void
+bitset_copy (bitset_t dest, const bitset_t src)
+{
+  memcpy (dest, src, sizeof (bitset_t));
+}
+
+static inline void
+bitset_not (bitset_t set)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < SBC_MAX / BITSET_WORD_BITS; ++bitset_i)
+    set[bitset_i] = ~set[bitset_i];
+  if (SBC_MAX % BITSET_WORD_BITS != 0)
+    set[BITSET_WORDS - 1] =
+      ((((bitset_word_t) 1 << SBC_MAX % BITSET_WORD_BITS) - 1)
+       & ~set[BITSET_WORDS - 1]);
+}
+
+static inline void
+bitset_merge (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] |= src[bitset_i];
+}
+
+static inline void
+bitset_mask (bitset_t dest, const bitset_t src)
+{
+  int bitset_i;
+  for (bitset_i = 0; bitset_i < BITSET_WORDS; ++bitset_i)
+    dest[bitset_i] &= src[bitset_i];
+}
+
+#ifndef __GNUC_PREREQ
+# if defined __GNUC__ && defined __GNUC_MINOR__
+#  define __GNUC_PREREQ(maj, min) \
+         ((__GNUC__ << 16) + __GNUC_MINOR__ >= ((maj) << 16) + (min))
+# else
+#  define __GNUC_PREREQ(maj, min) 0
+# endif
+#endif
+
+#if __GNUC_PREREQ (3,4)
+# undef __attribute_warn_unused_result__
+# define __attribute_warn_unused_result__ \
+   __attribute__ ((__warn_unused_result__))
+#else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+
+#ifndef FALLTHROUGH
+# if __GNUC__ < 7
+#  define FALLTHROUGH ((void) 0)
+# else
+#  define FALLTHROUGH __attribute__ ((__fallthrough__))
+# endif
+#endif
+
+#endif /*  _REGEX_INTERNAL_H */
diff --git a/headers-mingw/resource.h b/headers-mingw/resource.h
new file mode 100644
index 0000000..160aad2
--- /dev/null
+++ b/headers-mingw/resource.h
@@ -0,0 +1,79 @@
+/* Substitute for <sys/resource.h>.
+   Copyright (C) 2012-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_SYS_RESOURCE_H
+#define _GL_SYS_RESOURCE_H
+
+#if !HAVE_SYS_RESOURCE_H
+/* A platform that lacks <sys/resource.h>.  */
+
+/* Get 'struct timeval'.  */
+# include <sys/time.h>
+
+/* Define the RUSAGE_* constants.  */
+# define RUSAGE_SELF 0
+# define RUSAGE_CHILDREN -1
+
+# ifdef __cplusplus
+extern "C" {
+# endif
+
+# if !GNULIB_defined_struct_rusage
+/* All known platforms that lack <sys/resource.h> also lack any declaration
+   of struct rusage in any other header.  */
+struct rusage
+{
+  struct timeval ru_utime;      /* CPU time used in user mode */
+  struct timeval ru_stime;      /* CPU time used in system mode (kernel) */
+  long ru_maxrss;
+  long ru_ixrss;
+  long ru_idrss;
+  long ru_isrss;
+  long ru_minflt;
+  long ru_majflt;
+  long ru_nswap;
+  long ru_inblock;
+  long ru_oublock;
+  long ru_msgsnd;
+  long ru_msgrcv;
+  long ru_nsignals;
+  long ru_nvcsw;
+  long ru_nivcsw;
+};
+#  define GNULIB_defined_struct_rusage 1
+# endif
+
+# ifdef __cplusplus
+}
+# endif
+
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Declare overridden functions.  */
+
+
+#if !HAVE_GETRUSAGE
+extern int getrusage (int who, struct rusage *usage_p);
+#endif
+
+#endif /* _@GUARD_PREFIX@_SYS_RESOURCE_H */
diff --git a/headers-mingw/signal.h b/headers-mingw/signal.h
new file mode 100644
index 0000000..63539a2
--- /dev/null
+++ b/headers-mingw/signal.h
@@ -0,0 +1,264 @@
+/* A GNU-like <signal.h>.
+
+   Copyright (C) 2006-2018 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+
+
+/* Normal invocation convention.  */
+
+#ifndef _GL_SIGNAL_H
+#define _GL_SIGNAL_H
+
+/* Get pid_t.  */
+#include <sys/types.h>
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+/* A set or mask of signals.  */
+#if !GNULIB_defined_sigset_t
+typedef unsigned int sigset_t;
+# define GNULIB_defined_sigset_t 1
+#endif
+
+
+/* Define sighandler_t, the type of signal handlers.  A GNU extension.  */
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if !GNULIB_defined_sighandler_t
+typedef void (*sighandler_t) (int);
+# define GNULIB_defined_sighandler_t 1
+#endif
+#ifdef __cplusplus
+}
+#endif
+
+
+
+#ifndef SIGPIPE
+/* Define SIGPIPE to a value that does not overlap with other signals.  */
+#  define SIGPIPE 13
+#  define GNULIB_defined_SIGPIPE 1
+/* To actually use SIGPIPE, you also need the gnulib modules 'sigprocmask',
+   'write', 'stdio'.  */
+#endif
+
+
+
+/* Maximum signal number + 1.  */
+#ifndef NSIG
+# if defined __TANDEM
+#  define NSIG 32
+# endif
+#endif
+
+
+#if !(HAVE_PTHREAD_SIGMASK || defined pthread_sigmask)
+extern int pthread_sigmask(int how, const sigset_t *new_mask, sigset_t *old_mask);
+#endif
+
+
+#if !HAVE_RAISE
+extern int raise(int sig);
+#endif
+
+
+#ifndef GNULIB_defined_signal_blocking
+# define GNULIB_defined_signal_blocking 1
+#endif
+
+/* Maximum signal number + 1.  */
+#ifndef NSIG
+# define NSIG 32
+#endif
+
+/* This code supports only 32 signals.  */
+#if !GNULIB_defined_verify_NSIG_constraint
+typedef int verify_NSIG_constraint[NSIG <= 32 ? 1 : -1];
+# define GNULIB_defined_verify_NSIG_constraint 1
+#endif
+
+
+/* When also using extern inline, suppress the use of static inline in
+   standard headers of problematic Apple configurations, as Libc at
+   least through Libc-825.26 (2013-04-09) mishandles it; see, e.g.,
+   <https://lists.gnu.org/r/bug-gnulib/2012-12/msg00023.html>.
+   Perhaps Apple will fix this some day.  */
+#if (defined _GL_EXTERN_INLINE_IN_USE && defined __APPLE__ \
+     && (defined __i386__ || defined __x86_64__))
+# undef sigaddset
+# undef sigdelset
+# undef sigemptyset
+# undef sigfillset
+# undef sigismember
+#endif
+
+/* Test whether a given signal is contained in a signal set.  */
+#if !HAVE_SIGISMEMBER
+extern int sigismember(const sigset_t *set, int sig);
+# endif
+
+/* Initialize a signal set to the empty set.  */
+#if !HAVE_SIGEMPTYSET
+extern int sigemptyset(sigset_t *set);
+#endif
+
+
+/* Add a signal to a signal set.  */
+#if !HAVE_SIGADDSET
+extern int sigaddset(sigset_t *set, int sig);
+#endif
+
+
+/* Remove a signal from a signal set.  */
+#if !HAVE_SIGDELSET
+extern int sigdelset(sigset_t *set, int sig);
+# endif
+
+/* Fill a signal set with all possible signals.  */
+#if !HAVE_SIGFILLSET
+extern int sigfillset(sigset_t *set);
+#endif
+
+
+/* Return the set of those blocked signals that are pending.  */
+#if !HAVE_SIGPENDING
+extern int sigpending(sigset_t *set);
+#endif
+
+/* If OLD_SET is not NULL, put the current set of blocked signals in *OLD_SET.
+   Then, if SET is not NULL, affect the current set of blocked signals by
+   combining it with *SET as indicated in OPERATION.
+   In this implementation, you are not allowed to change a signal handler
+   while the signal is blocked.  */
+#ifndef SIG_BLOCK
+# define SIG_BLOCK   0  /* blocked_set = blocked_set | *set; */
+#endif
+#ifndef SIG_SETMASK
+# define SIG_SETMASK 1  /* blocked_set = *set; */
+#endif
+#ifndef SIG_UNBLOCK
+# define SIG_UNBLOCK 2  /* blocked_set = blocked_set & ~*set; */
+#endif
+#if !HAVE_SIGPROCMASK
+extern int sigprocmask(int operation, const sigset_t *set, sigset_t *old_set);
+# endif
+
+/* Install the handler FUNC for signal SIG, and return the previous
+   handler.  */
+#ifdef __cplusplus
+extern "C" {
+#endif
+#if !GNULIB_defined_function_taking_int_returning_void_t
+typedef void (*_gl_function_taking_int_returning_void_t) (int);
+# define GNULIB_defined_function_taking_int_returning_void_t 1
+#endif
+#ifdef __cplusplus
+}
+#endif
+#if !HAVE_SIGNAL
+extern _gl_function_taking_int_returning_void_t signal(int sig, _gl_function_taking_int_returning_void_t func);
+#endif
+
+
+extern int _gl_raise_SIGPIPE (void);
+
+#if !HAVE_SIGACTION
+# if !GNULIB_defined_siginfo_types
+
+/* Present to allow compilation, but unsupported by gnulib.  */
+union sigval
+{
+  int sival_int;
+  void *sival_ptr;
+};
+
+/* Present to allow compilation, but unsupported by gnulib.  */
+struct siginfo_t
+{
+  int si_signo;
+  int si_code;
+  int si_errno;
+  pid_t si_pid;
+  int si_uid;
+  void *si_addr;
+  int si_status;
+  long si_band;
+  union sigval si_value;
+};
+typedef struct siginfo_t siginfo_t;
+
+#  define GNULIB_defined_siginfo_types 1
+# endif
+
+
+/* We assume that platforms which lack the sigaction() function also lack
+   the 'struct sigaction' type, and vice versa.  */
+
+# if !GNULIB_defined_struct_sigaction
+
+struct sigaction
+{
+  union
+  {
+    void (*_sa_handler) (int);
+    /* Present to allow compilation, but unsupported by gnulib.  POSIX
+       says that implementations may, but not must, make sa_sigaction
+       overlap with sa_handler, but we know of no implementation where
+       they do not overlap.  */
+    void (*_sa_sigaction) (int, siginfo_t *, void *);
+  } _sa_func;
+  sigset_t sa_mask;
+  /* Not all POSIX flags are supported.  */
+  int sa_flags;
+};
+#  define sa_handler _sa_func._sa_handler
+#  define sa_sigaction _sa_func._sa_sigaction
+/* Unsupported flags are not present.  */
+#  define SA_RESETHAND 1
+#  define SA_NODEFER 2
+#  define SA_RESTART 4
+
+#  define GNULIB_defined_struct_sigaction 1
+# endif
+
+extern int sigaction(int, const struct sigaction *restrict,
+                                   struct sigaction *restrict);
+#endif
+
+/* Some systems don't have SA_NODEFER.  */
+#ifndef SA_NODEFER
+# define SA_NODEFER 0
+#endif
+
+/* Out-of-range substitutes make a good fallback for uncatchable
+   signals.  */
+#ifndef SIGKILL
+# define SIGKILL (-1)
+#endif
+#ifndef SIGSTOP
+# define SIGSTOP (-1)
+#endif
+
+#if !defined(HAVE_KILL)
+extern int kill(pid_t pid, int sig);
+#endif
+
+#endif /* _@GUARD_PREFIX@_SIGNAL_H */
diff --git a/headers-mingw/stdlib.h b/headers-mingw/stdlib.h
new file mode 100644
index 0000000..55a0e5b
--- /dev/null
+++ b/headers-mingw/stdlib.h
@@ -0,0 +1,344 @@
+/* A GNU-like <stdlib.h>.
+
+   Copyright (C) 1995, 2001-2004, 2006-2018 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Normal invocation convention.  */
+
+#ifndef _GL_STDLIB_H
+
+#define _GL_STDLIB_H
+
+/* Native Windows platforms declare mktemp() in <io.h>.  */
+#if (defined _WIN32 && ! defined __CYGWIN__)
+# include <io.h>
+#endif
+
+/* OSF/1 5.1 declares 'struct random_data' in <random.h>, which is included
+   from <stdlib.h> if _REENTRANT is defined.  Include it whenever we need
+   'struct random_data'.  */
+#if HAVE_RANDOM_H
+# include <random.h>
+#endif
+
+#if !HAVE_RANDOM_R
+# include <stdint.h>
+#endif
+
+/* Define 'struct random_data'.
+   But allow multiple gnulib generated <stdlib.h> replacements to coexist.  */
+#if !GNULIB_defined_struct_random_data
+typedef struct random_data
+{
+  int *fptr;                /* Front pointer.  */
+  int *rptr;                /* Rear pointer.  */
+  int *state;               /* Array of state values.  */
+  int rand_type;                /* Type of random number generator.  */
+  int rand_deg;                 /* Degree of random number generator.  */
+  int rand_sep;                 /* Distance between front and rear.  */
+  int *end_ptr;             /* Pointer behind state table.  */
+};
+# define GNULIB_defined_struct_random_data 1
+#endif
+
+/* The __attribute__ feature is available in gcc versions 2.5 and later.
+   The attribute __pure__ was added in gcc 2.96.  */
+#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+# define _GL_ATTRIBUTE_PURE __attribute__ ((__pure__))
+#else
+# define _GL_ATTRIBUTE_PURE /* empty */
+#endif
+
+/* The definition of _Noreturn is copied here.  */
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Some systems do not define EXIT_*, despite otherwise supporting C89.  */
+#ifndef EXIT_SUCCESS
+# define EXIT_SUCCESS 0
+#endif
+/* Tandem/NSK and other platforms that define EXIT_FAILURE as -1 interfere
+   with proper operation of xargs.  */
+#ifndef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#elif EXIT_FAILURE != 1
+# undef EXIT_FAILURE
+# define EXIT_FAILURE 1
+#endif
+
+
+/* Terminate the current process with the given return code, without running
+   the 'atexit' handlers.  */
+#if !HAVE__EXIT
+extern void _Exit(int status);
+#endif
+
+/* Parse a signed decimal integer.
+   Returns the value of the integer.  Errors are not detected.  */
+#if !HAVE_ATOLL
+extern long long atoll(const char *string);
+#endif
+
+#if !HAVE_CANONICALIZE_FILE_NAME
+extern char * canonicalize_file_name(const char *name);
+#endif
+
+/* Store max(NELEM,3) load average numbers in LOADAVG[].
+   The three numbers are the load average of the last 1 minute, the last 5
+   minutes, and the last 15 minutes, respectively.
+   LOADAVG is an array of NELEM numbers.  */
+#if !HAVE_GETLOADAVG
+extern int getloadavg(double loadavg[], int nelem);
+#endif
+
+
+/* Assuming *OPTIONP is a comma separated list of elements of the form
+   "token" or "token=value", getsubopt parses the first of these elements.
+   If the first element refers to a "token" that is member of the given
+   NULL-terminated array of tokens:
+     - It replaces the comma with a NUL byte, updates *OPTIONP to point past
+       the first option and the comma, sets *VALUEP to the value of the
+       element (or NULL if it doesn't contain an "=" sign),
+     - It returns the index of the "token" in the given array of tokens.
+   Otherwise it returns -1, and *OPTIONP and *VALUEP are undefined.
+   For more details see the POSIX:2001 specification.
+   http://www.opengroup.org/susv3xsh/getsubopt.html */
+#if !HAVE_GETSUBOPT
+extern int getsubopt(char **optionp, char *const *tokens, char **valuep);
+#endif
+
+
+/* Change the ownership and access permission of the slave side of the
+   pseudo-terminal whose master side is specified by FD.  */
+#if !HAVE_GRANTPT
+extern int grantpt(int fd);
+#endif
+
+
+/* Create a unique temporary directory from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the directory name unique.
+   Returns TEMPLATE, or a null pointer if it cannot get a unique name.
+   The directory is created mode 700.  */
+#if !HAVE_MKDTEMP
+extern char * mkdtemp(char *template);
+#endif
+
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   The file is then created, with the specified flags, ensuring it didn't exist
+   before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+#if !HAVE_MKOSTEMP
+extern int mkostemp(char *template, int flags);
+#endif
+
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE before a suffix of length
+   SUFFIXLEN must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   The file is then created, with the specified flags, ensuring it didn't exist
+   before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+#if !HAVE_MKOSTEMPS
+extern int mkostemps(char * template, int suffixlen, int flags);
+#endif
+
+
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The file is then created, ensuring it didn't exist before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+#if !HAVE_MKSTEMP
+extern int mkstemp(char * template);
+#endif
+
+
+/* Create a unique temporary file from TEMPLATE.
+   The last six characters of TEMPLATE prior to a suffix of length
+   SUFFIXLEN must be "XXXXXX";
+   they are replaced with a string that makes the file name unique.
+   The file is then created, ensuring it didn't exist before.
+   The file is created read-write (mask at least 0600 & ~umask), but it may be
+   world-readable and world-writable (mask 0666 & ~umask), depending on the
+   implementation.
+   Returns the open file descriptor if successful, otherwise -1 and errno
+   set.  */
+#if !HAVE_MKSTEMPS
+extern int mkstemps(char * template, int suffixlen);
+#endif
+
+
+/* Return an FD open to the master side of a pseudo-terminal.  Flags should
+   include O_RDWR, and may also include O_NOCTTY.  */
+# if !HAVE_POSIX_OPENPT
+extern int posix_openpt(int flags);
+#endif
+
+/* Return the pathname of the pseudo-terminal slave associated with
+   the master FD is open on, or NULL on errors.  */
+#if !HAVE_PTSNAME
+extern char * ptsname(int fd);
+#endif
+
+
+/* Set the pathname of the pseudo-terminal slave associated with
+   the master FD is open on and return 0, or set errno and return
+   non-zero on errors.  */
+#if !HAVE_PTSNAME_R
+extern int ptsname_r(int fd, char *buf, size_t len);
+#endif
+
+/* Sort an array of NMEMB elements, starting at address BASE, each element
+   occupying SIZE bytes, in ascending order according to the comparison
+   function COMPARE.  */
+#if !HAVE_QSORT_R
+extern void qsort_r(void *base, size_t nmemb, size_t size,
+                                  int (*compare) (void const *, void const *,
+                                                  void *),
+                                  void *arg);
+#endif
+
+#ifndef RAND_MAX
+# define RAND_MAX 2147483647
+#endif
+
+#if !HAVE_RANDOM
+extern long random(void);
+#endif
+
+#if !HAVE_SRANDOM
+extern void srandom(unsigned int seed);
+#endif
+
+
+#if !HAVE_INITSTATE
+extern char * initstate(unsigned int seed, char *buf, size_t buf_size);
+#endif
+
+#if !HAVE_SETSTATE
+extern char * setstate(char *arg_state);
+#endif
+
+
+#if !HAVE_RANDOM_R
+extern int random_r(struct random_data *buf, int *result);
+#endif
+
+#  if !HAVE_SRANDOM_R
+extern int srandom_r(unsigned int seed, struct random_data *rand_state);
+#endif
+
+#if !HAVE_INITSTATE_R
+extern int initstate_r(unsigned int seed, char *buf, size_t buf_size,
+    struct random_data *rand_state);
+#endif
+
+#if !HAVE_SETSTATE_R
+extern int setstate_r(char *arg_state, struct random_data *rand_state);
+#endif
+
+#if !HAVE_REALLOCARRAY
+extern void * reallocarray(void *ptr, size_t nmemb, size_t size);
+#endif
+
+#if !HAVE_REALPATH
+extern char * realpath(const char *name, char *resolved);
+#endif
+
+/* Test a user response to a question.
+   Return 1 if it is affirmative, 0 if it is negative, or -1 if not clear.  */
+#if !HAVE_RPMATCH
+extern int rpmatch(const char *response);
+#endif
+
+/* Look up NAME in the environment, returning 0 in insecure situations.  */
+#if !HAVE_SECURE_GETENV
+extern char * secure_getenv(char const *name);
+#endif
+
+
+/* Set NAME to VALUE in the environment.
+   If REPLACE is nonzero, overwrite an existing value.  */
+#if !HAVE_SETENV
+extern int setenv(const char *name, const char *value, int replace);
+#endif
+
+/* Parse a double from STRING, updating ENDP if appropriate.  */
+#if !HAVE_STRTOD
+extern double strtod(const char *str, char **endp);
+#endif
+
+/* Parse a signed integer whose textual representation starts at STRING.
+   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+   it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+   "0x").
+   If ENDPTR is not NULL, the address of the first byte after the integer is
+   stored in *ENDPTR.
+   Upon overflow, the return value is LLONG_MAX or LLONG_MIN, and errno is set
+   to ERANGE.  */
+#if !HAVE_STRTOLL
+extern long long strtoll(const char *string, char **endptr, int base);
+#endif
+
+/* Parse an unsigned integer whose textual representation starts at STRING.
+   The integer is expected to be in base BASE (2 <= BASE <= 36); if BASE == 0,
+   it may be decimal or octal (with prefix "0") or hexadecimal (with prefix
+   "0x").
+   If ENDPTR is not NULL, the address of the first byte after the integer is
+   stored in *ENDPTR.
+   Upon overflow, the return value is ULLONG_MAX, and errno is set to
+   ERANGE.  */
+#if !HAVE_STRTOULL
+extern unsigned long long strtoull(const char *string, char **endptr, int base);
+#endif
+
+
+/* Unlock the slave side of the pseudo-terminal whose master side is specified
+   by FD, so that it can be opened.  */
+#if !HAVE_UNLOCKPT
+extern int unlockpt(int fd);
+#endif
+
+/* Remove the variable NAME from the environment.  */
+#if !HAVE_UNSETENV
+extern int unsetenv(const char *name);
+#endif
+
+#endif /* _@GUARD_PREFIX@_STDLIB_H */
+
diff --git a/headers-mingw/sys_cdefs.h b/headers-mingw/sys_cdefs.h
new file mode 100644
index 0000000..98cf749
--- /dev/null
+++ b/headers-mingw/sys_cdefs.h
@@ -0,0 +1,514 @@
+/* Copyright (C) 1992-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef	_SYS_CDEFS_H
+#define	_SYS_CDEFS_H	1
+
+/* We are almost always included from features.h. */
+#ifndef _FEATURES_H
+# include <features.h>
+#endif
+
+/* The GNU libc does not support any K&R compilers or the traditional mode
+   of ISO C compilers anymore.  Check for some of the combinations not
+   anymore supported.  */
+#if defined __GNUC__ && !defined __STDC__
+# error "You need a ISO C conforming compiler to use the glibc headers"
+#endif
+
+/* Some user header file might have defined this before.  */
+#undef	__P
+#undef	__PMT
+
+#ifdef __GNUC__
+
+/* All functions, except those with callbacks or those that
+   synchronize memory, are leaf functions.  */
+# if __GNUC_PREREQ (4, 6) && !defined _LIBC
+#  define __LEAF , __leaf__
+#  define __LEAF_ATTR __attribute__ ((__leaf__))
+# else
+#  define __LEAF
+#  define __LEAF_ATTR
+# endif
+
+/* GCC can always grok prototypes.  For C++ programs we add throw()
+   to help it optimize the function calls.  But this works only with
+   gcc 2.8.x and egcs.  For gcc 3.2 and up we even mark C functions
+   as non-throwing using a function attribute since programs can use
+   the -fexceptions options for C code as well.  */
+# if !defined __cplusplus && __GNUC_PREREQ (3, 3)
+#  define __THROW	__attribute__ ((__nothrow__ __LEAF))
+#  define __THROWNL	__attribute__ ((__nothrow__))
+#  define __NTH(fct)	__attribute__ ((__nothrow__ __LEAF)) fct
+#  define __NTHNL(fct)  __attribute__ ((__nothrow__)) fct
+# else
+#  if defined __cplusplus && __GNUC_PREREQ (2,8)
+#   define __THROW	throw ()
+#   define __THROWNL	throw ()
+#   define __NTH(fct)	__LEAF_ATTR fct throw ()
+#   define __NTHNL(fct) fct throw ()
+#  else
+#   define __THROW
+#   define __THROWNL
+#   define __NTH(fct)	fct
+#   define __NTHNL(fct) fct
+#  endif
+# endif
+
+#else	/* Not GCC.  */
+
+# if (defined __cplusplus						\
+      || (defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L))
+#  define __inline	inline
+# else
+#  define __inline		/* No inline functions.  */
+# endif
+
+# define __THROW
+# define __THROWNL
+# define __NTH(fct)	fct
+
+#endif	/* GCC.  */
+
+/* Compilers that are not clang may object to
+       #if defined __clang__ && __has_extension(...)
+   even though they do not need to evaluate the right-hand side of the &&.  */
+#if defined __clang__ && defined __has_extension
+# define __glibc_clang_has_extension(ext) __has_extension (ext)
+#else
+# define __glibc_clang_has_extension(ext) 0
+#endif
+
+/* These two macros are not used in glibc anymore.  They are kept here
+   only because some other projects expect the macros to be defined.  */
+#define __P(args)	args
+#define __PMT(args)	args
+
+/* For these things, GCC behaves the ANSI way normally,
+   and the non-ANSI way under -traditional.  */
+
+#define __CONCAT(x,y)	x ## y
+#define __STRING(x)	#x
+
+/* This is not a typedef so `const __ptr_t' does the right thing.  */
+#define __ptr_t void *
+
+
+/* C++ needs to know that types and declarations are C, not C++.  */
+#ifdef	__cplusplus
+# define __BEGIN_DECLS	extern "C" {
+# define __END_DECLS	}
+#else
+# define __BEGIN_DECLS
+# define __END_DECLS
+#endif
+
+
+/* Fortify support.  */
+#define __bos(ptr) __builtin_object_size (ptr, __USE_FORTIFY_LEVEL > 1)
+#define __bos0(ptr) __builtin_object_size (ptr, 0)
+
+#if __GNUC_PREREQ (4,3)
+# define __warndecl(name, msg) \
+  extern void name (void) __attribute__((__warning__ (msg)))
+# define __warnattr(msg) __attribute__((__warning__ (msg)))
+# define __errordecl(name, msg) \
+  extern void name (void) __attribute__((__error__ (msg)))
+#else
+# define __warndecl(name, msg) extern void name (void)
+# define __warnattr(msg)
+# define __errordecl(name, msg) extern void name (void)
+#endif
+
+/* Support for flexible arrays.
+   Headers that should use flexible arrays only if they're "real"
+   (e.g. only if they won't affect sizeof()) should test
+   #if __glibc_c99_flexarr_available.  */
+#if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+# define __flexarr	[]
+# define __glibc_c99_flexarr_available 1
+#elif __GNUC_PREREQ (2,97)
+/* GCC 2.97 supports C99 flexible array members as an extension,
+   even when in C89 mode or compiling C++ (any version).  */
+# define __flexarr	[]
+# define __glibc_c99_flexarr_available 1
+#elif defined __GNUC__
+/* Pre-2.97 GCC did not support C99 flexible arrays but did have
+   an equivalent extension with slightly different notation.  */
+# define __flexarr	[0]
+# define __glibc_c99_flexarr_available 1
+#else
+/* Some other non-C99 compiler.  Approximate with [1].  */
+# define __flexarr	[1]
+# define __glibc_c99_flexarr_available 0
+#endif
+
+
+/* __asm__ ("xyz") is used throughout the headers to rename functions
+   at the assembly language level.  This is wrapped by the __REDIRECT
+   macro, in order to support compilers that can do this some other
+   way.  When compilers don't support asm-names at all, we have to do
+   preprocessor tricks instead (which don't have exactly the right
+   semantics, but it's the best we can do).
+
+   Example:
+   int __REDIRECT(setpgrp, (__pid_t pid, __pid_t pgrp), setpgid); */
+
+#if defined __GNUC__ && __GNUC__ >= 2
+
+# define __REDIRECT(name, proto, alias) name proto __asm__ (__ASMNAME (#alias))
+# ifdef __cplusplus
+#  define __REDIRECT_NTH(name, proto, alias) \
+     name proto __THROW __asm__ (__ASMNAME (#alias))
+#  define __REDIRECT_NTHNL(name, proto, alias) \
+     name proto __THROWNL __asm__ (__ASMNAME (#alias))
+# else
+#  define __REDIRECT_NTH(name, proto, alias) \
+     name proto __asm__ (__ASMNAME (#alias)) __THROW
+#  define __REDIRECT_NTHNL(name, proto, alias) \
+     name proto __asm__ (__ASMNAME (#alias)) __THROWNL
+# endif
+# define __ASMNAME(cname)  __ASMNAME2 (__USER_LABEL_PREFIX__, cname)
+# define __ASMNAME2(prefix, cname) __STRING (prefix) cname
+
+/*
+#elif __SOME_OTHER_COMPILER__
+
+# define __REDIRECT(name, proto, alias) name proto; \
+	_Pragma("let " #name " = " #alias)
+*/
+#endif
+
+/* GCC has various useful declarations that can be made with the
+   `__attribute__' syntax.  All of the ways we use this do fine if
+   they are omitted for compilers that don't understand it. */
+#if !defined __GNUC__ || __GNUC__ < 2
+# define __attribute__(xyz)	/* Ignore */
+#endif
+
+/* At some point during the gcc 2.96 development the `malloc' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.  */
+#if __GNUC_PREREQ (2,96)
+# define __attribute_malloc__ __attribute__ ((__malloc__))
+#else
+# define __attribute_malloc__ /* Ignore */
+#endif
+
+/* Tell the compiler which arguments to an allocation function
+   indicate the size of the allocation.  */
+#if __GNUC_PREREQ (4, 3)
+# define __attribute_alloc_size__(params) \
+  __attribute__ ((__alloc_size__ params))
+#else
+# define __attribute_alloc_size__(params) /* Ignore.  */
+#endif
+
+/* At some point during the gcc 2.96 development the `pure' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.  */
+#if __GNUC_PREREQ (2,96)
+# define __attribute_pure__ __attribute__ ((__pure__))
+#else
+# define __attribute_pure__ /* Ignore */
+#endif
+
+/* This declaration tells the compiler that the value is constant.  */
+#if __GNUC_PREREQ (2,5)
+# define __attribute_const__ __attribute__ ((__const__))
+#else
+# define __attribute_const__ /* Ignore */
+#endif
+
+/* At some point during the gcc 3.1 development the `used' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.  */
+#if __GNUC_PREREQ (3,1)
+# define __attribute_used__ __attribute__ ((__used__))
+# define __attribute_noinline__ __attribute__ ((__noinline__))
+#else
+# define __attribute_used__ __attribute__ ((__unused__))
+# define __attribute_noinline__ /* Ignore */
+#endif
+
+/* Since version 3.2, gcc allows marking deprecated functions.  */
+#if __GNUC_PREREQ (3,2)
+# define __attribute_deprecated__ __attribute__ ((__deprecated__))
+#else
+# define __attribute_deprecated__ /* Ignore */
+#endif
+
+/* Since version 4.5, gcc also allows one to specify the message printed
+   when a deprecated function is used.  clang claims to be gcc 4.2, but
+   may also support this feature.  */
+#if __GNUC_PREREQ (4,5) || \
+    __glibc_clang_has_extension (__attribute_deprecated_with_message__)
+# define __attribute_deprecated_msg__(msg) \
+	 __attribute__ ((__deprecated__ (msg)))
+#else
+# define __attribute_deprecated_msg__(msg) __attribute_deprecated__
+#endif
+
+/* At some point during the gcc 2.8 development the `format_arg' attribute
+   for functions was introduced.  We don't want to use it unconditionally
+   (although this would be possible) since it generates warnings.
+   If several `format_arg' attributes are given for the same function, in
+   gcc-3.0 and older, all but the last one are ignored.  In newer gccs,
+   all designated arguments are considered.  */
+#if __GNUC_PREREQ (2,8)
+# define __attribute_format_arg__(x) __attribute__ ((__format_arg__ (x)))
+#else
+# define __attribute_format_arg__(x) /* Ignore */
+#endif
+
+/* At some point during the gcc 2.97 development the `strfmon' format
+   attribute for functions was introduced.  We don't want to use it
+   unconditionally (although this would be possible) since it
+   generates warnings.  */
+#if __GNUC_PREREQ (2,97)
+# define __attribute_format_strfmon__(a,b) \
+  __attribute__ ((__format__ (__strfmon__, a, b)))
+#else
+# define __attribute_format_strfmon__(a,b) /* Ignore */
+#endif
+
+/* The nonnull function attribute marks pointer parameters that
+   must not be NULL.  Do not define __nonnull if it is already defined,
+   for portability when this file is used in Gnulib.  */
+#ifndef __nonnull
+# if __GNUC_PREREQ (3,3)
+#  define __nonnull(params) __attribute__ ((__nonnull__ params))
+# else
+#  define __nonnull(params)
+# endif
+#endif
+
+/* If fortification mode, we warn about unused results of certain
+   function calls which can lead to problems.  */
+#if __GNUC_PREREQ (3,4)
+# define __attribute_warn_unused_result__ \
+   __attribute__ ((__warn_unused_result__))
+# if defined __USE_FORTIFY_LEVEL && __USE_FORTIFY_LEVEL > 0
+#  define __wur __attribute_warn_unused_result__
+# endif
+#else
+# define __attribute_warn_unused_result__ /* empty */
+#endif
+#ifndef __wur
+# define __wur /* Ignore */
+#endif
+
+/* Forces a function to be always inlined.  */
+#if __GNUC_PREREQ (3,2)
+/* The Linux kernel defines __always_inline in stddef.h (283d7573), and
+   it conflicts with this definition.  Therefore undefine it first to
+   allow either header to be included first.  */
+# undef __always_inline
+# define __always_inline __inline __attribute__ ((__always_inline__))
+#else
+# undef __always_inline
+# define __always_inline __inline
+#endif
+
+/* Associate error messages with the source location of the call site rather
+   than with the source location inside the function.  */
+#if __GNUC_PREREQ (4,3)
+# define __attribute_artificial__ __attribute__ ((__artificial__))
+#else
+# define __attribute_artificial__ /* Ignore */
+#endif
+
+/* GCC 4.3 and above with -std=c99 or -std=gnu99 implements ISO C99
+   inline semantics, unless -fgnu89-inline is used.  Using __GNUC_STDC_INLINE__
+   or __GNUC_GNU_INLINE is not a good enough check for gcc because gcc versions
+   older than 4.3 may define these macros and still not guarantee GNU inlining
+   semantics.
+
+   clang++ identifies itself as gcc-4.2, but has support for GNU inlining
+   semantics, that can be checked fot by using the __GNUC_STDC_INLINE_ and
+   __GNUC_GNU_INLINE__ macro definitions.  */
+#if (!defined __cplusplus || __GNUC_PREREQ (4,3) \
+     || (defined __clang__ && (defined __GNUC_STDC_INLINE__ \
+			       || defined __GNUC_GNU_INLINE__)))
+# if defined __GNUC_STDC_INLINE__ || defined __cplusplus
+#  define __extern_inline extern __inline __attribute__ ((__gnu_inline__))
+#  define __extern_always_inline \
+  extern __always_inline __attribute__ ((__gnu_inline__))
+# else
+#  define __extern_inline extern __inline
+#  define __extern_always_inline extern __always_inline
+# endif
+#endif
+
+#ifdef __extern_always_inline
+# define __fortify_function __extern_always_inline __attribute_artificial__
+#endif
+
+/* GCC 4.3 and above allow passing all anonymous arguments of an
+   __extern_always_inline function to some other vararg function.  */
+#if __GNUC_PREREQ (4,3)
+# define __va_arg_pack() __builtin_va_arg_pack ()
+# define __va_arg_pack_len() __builtin_va_arg_pack_len ()
+#endif
+
+/* It is possible to compile containing GCC extensions even if GCC is
+   run in pedantic mode if the uses are carefully marked using the
+   `__extension__' keyword.  But this is not generally available before
+   version 2.8.  */
+#if !__GNUC_PREREQ (2,8)
+# define __extension__		/* Ignore */
+#endif
+
+/* __restrict is known in EGCS 1.2 and above. */
+#if !__GNUC_PREREQ (2,92)
+# if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#  define __restrict	restrict
+# else
+#  define __restrict	/* Ignore */
+# endif
+#endif
+
+/* ISO C99 also allows to declare arrays as non-overlapping.  The syntax is
+     array_name[restrict]
+   GCC 3.1 supports this.  */
+#if __GNUC_PREREQ (3,1) && !defined __GNUG__
+# define __restrict_arr	__restrict
+#else
+# ifdef __GNUC__
+#  define __restrict_arr	/* Not supported in old GCC.  */
+# else
+#  if defined __STDC_VERSION__ && __STDC_VERSION__ >= 199901L
+#   define __restrict_arr	restrict
+#  else
+/* Some other non-C99 compiler.  */
+#   define __restrict_arr	/* Not supported.  */
+#  endif
+# endif
+#endif
+
+#if __GNUC__ >= 3
+# define __glibc_unlikely(cond)	__builtin_expect ((cond), 0)
+# define __glibc_likely(cond)	__builtin_expect ((cond), 1)
+#else
+# define __glibc_unlikely(cond)	(cond)
+# define __glibc_likely(cond)	(cond)
+#endif
+
+#ifdef __has_attribute
+# define __glibc_has_attribute(attr)	__has_attribute (attr)
+#else
+# define __glibc_has_attribute(attr)	0
+#endif
+
+#if (!defined _Noreturn \
+     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
+     &&  !__GNUC_PREREQ (4,7))
+# if __GNUC_PREREQ (2,8)
+#  define _Noreturn __attribute__ ((__noreturn__))
+# else
+#  define _Noreturn
+# endif
+#endif
+
+#if __GNUC_PREREQ (8, 0)
+/* Describes a char array whose address can safely be passed as the first
+   argument to strncpy and strncat, as the char array is not necessarily
+   a NUL-terminated string.  */
+# define __attribute_nonstring__ __attribute__ ((__nonstring__))
+#else
+# define __attribute_nonstring__
+#endif
+
+#if (!defined _Static_assert && !defined __cplusplus \
+     && (defined __STDC_VERSION__ ? __STDC_VERSION__ : 0) < 201112 \
+     && (!__GNUC_PREREQ (4, 6) || defined __STRICT_ANSI__))
+# define _Static_assert(expr, diagnostic) \
+    extern int (*__Static_assert_function (void)) \
+      [!!sizeof (struct { int __error_if_negative: (expr) ? 2 : -1; })]
+#endif
+
+/* The #ifndef lets Gnulib avoid including these on non-glibc
+   platforms, where the includes typically do not exist.  */
+#ifndef __WORDSIZE
+# include <bits/wordsize.h>
+# include <bits/long-double.h>
+#endif
+
+#if defined __LONG_DOUBLE_MATH_OPTIONAL && defined __NO_LONG_DOUBLE_MATH
+# define __LDBL_COMPAT 1
+# ifdef __REDIRECT
+#  define __LDBL_REDIR1(name, proto, alias) __REDIRECT (name, proto, alias)
+#  define __LDBL_REDIR(name, proto) \
+  __LDBL_REDIR1 (name, proto, __nldbl_##name)
+#  define __LDBL_REDIR1_NTH(name, proto, alias) __REDIRECT_NTH (name, proto, alias)
+#  define __LDBL_REDIR_NTH(name, proto) \
+  __LDBL_REDIR1_NTH (name, proto, __nldbl_##name)
+#  define __LDBL_REDIR1_DECL(name, alias) \
+  extern __typeof (name) name __asm (__ASMNAME (#alias));
+#  define __LDBL_REDIR_DECL(name) \
+  extern __typeof (name) name __asm (__ASMNAME ("__nldbl_" #name));
+#  define __REDIRECT_LDBL(name, proto, alias) \
+  __LDBL_REDIR1 (name, proto, __nldbl_##alias)
+#  define __REDIRECT_NTH_LDBL(name, proto, alias) \
+  __LDBL_REDIR1_NTH (name, proto, __nldbl_##alias)
+# endif
+#endif
+#if !defined __LDBL_COMPAT || !defined __REDIRECT
+# define __LDBL_REDIR1(name, proto, alias) name proto
+# define __LDBL_REDIR(name, proto) name proto
+# define __LDBL_REDIR1_NTH(name, proto, alias) name proto __THROW
+# define __LDBL_REDIR_NTH(name, proto) name proto __THROW
+# define __LDBL_REDIR_DECL(name)
+# ifdef __REDIRECT
+#  define __REDIRECT_LDBL(name, proto, alias) __REDIRECT (name, proto, alias)
+#  define __REDIRECT_NTH_LDBL(name, proto, alias) \
+  __REDIRECT_NTH (name, proto, alias)
+# endif
+#endif
+
+/* __glibc_macro_warning (MESSAGE) issues warning MESSAGE.  This is
+   intended for use in preprocessor macros.
+
+   Note: MESSAGE must be a _single_ string; concatenation of string
+   literals is not supported.  */
+#if __GNUC_PREREQ (4,8) || __glibc_clang_prereq (3,5)
+# define __glibc_macro_warning1(message) _Pragma (#message)
+# define __glibc_macro_warning(message) \
+  __glibc_macro_warning1 (GCC warning message)
+#else
+# define __glibc_macro_warning(msg)
+#endif
+
+/* Generic selection (ISO C11) is a C-only feature, available in GCC
+   since version 4.9.  Previous versions do not provide generic
+   selection, even though they might set __STDC_VERSION__ to 201112L,
+   when in -std=c11 mode.  Thus, we must check for !defined __GNUC__
+   when testing __STDC_VERSION__ for generic selection support.
+   On the other hand, Clang also defines __GNUC__, so a clang-specific
+   check is required to enable the use of generic selection.  */
+#if !defined __cplusplus \
+    && (__GNUC_PREREQ (4, 9) \
+	|| __glibc_clang_has_extension (c_generic_selections) \
+	|| (!defined __GNUC__ && defined __STDC_VERSION__ \
+	    && __STDC_VERSION__ >= 201112L))
+# define __HAVE_GENERIC_SELECTION 1
+#else
+# define __HAVE_GENERIC_SELECTION 0
+#endif
+
+#endif	 /* sys/cdefs.h */
diff --git a/headers-mingw/sys_ioctl.h b/headers-mingw/sys_ioctl.h
new file mode 100644
index 0000000..80e9d7b
--- /dev/null
+++ b/headers-mingw/sys_ioctl.h
@@ -0,0 +1,36 @@
+/* Substitute for and wrapper around <sys/ioctl.h>.
+   Copyright (C) 2008-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_SYS_IOCTL_H
+
+#define _GL_SYS_IOCTL_H
+
+/* AIX 5.1 and Solaris 10 declare ioctl() in <unistd.h> and in <stropts.h>,
+   but not in <sys/ioctl.h>.
+   Haiku declares ioctl() in <unistd.h>, but not in <sys/ioctl.h>.
+   But avoid namespace pollution on glibc systems.  */
+#ifndef __GLIBC__
+# include <unistd.h>
+#endif
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+/* Declare overridden functions.  */
+
+#endif /* _@GUARD_PREFIX@_SYS_IOCTL_H */
diff --git a/headers-mingw/sys_stat.h b/headers-mingw/sys_stat.h
new file mode 100644
index 0000000..2b06b15
--- /dev/null
+++ b/headers-mingw/sys_stat.h
@@ -0,0 +1,506 @@
+/* Provide a more complete sys/stat.h header file.
+   Copyright (C) 2005-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Eric Blake, Paul Eggert, and Jim Meyering.  */
+
+/* This file is supposed to be used on platforms where <sys/stat.h> is
+   incomplete.  It is intended to provide definitions and prototypes
+   needed by an application.  Start with what the system provides.  */
+
+/* Normal invocation convention.  */
+
+#ifndef _GL_SYS_STAT_H
+
+/* Get nlink_t.
+   May also define off_t to a 64-bit type on native Windows.  */
+#include <sys/types.h>
+
+/* Get struct timespec.  */
+#include <time.h>
+
+#define _GL_SYS_STAT_H
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+/* Before doing "#define mkdir rpl_mkdir" below, we need to include all
+   headers that may declare mkdir().  Native Windows platforms declare mkdir
+   in <io.h> and/or <direct.h>, not in <unistd.h>.  */
+#if defined _WIN32 && ! defined __CYGWIN__
+# include <io.h>     /* mingw32, mingw64 */
+# include <direct.h> /* mingw64, MSVC 9 */
+#endif
+
+//# if !GNULIB_defined_struct_stat
+//struct stat
+//{
+//  dev_t st_dev;
+//  ino_t st_ino;
+//  mode_t st_mode;
+//  nlink_t st_nlink;
+//#  if 0
+//  uid_t st_uid;
+//#  else /* uid_t is not defined by default on native Windows.  */
+//  int st_uid;
+//#  endif
+//#  if 0
+//  gid_t st_gid;
+//#  else /* gid_t is not defined by default on native Windows.  */
+//  int st_gid;
+//#  endif
+//  dev_t st_rdev;
+//  off_t st_size;
+//#  if 0
+//  blksize_t st_blksize;
+//  blkcnt_t st_blocks;
+//#  endif
+//
+////#  if @WINDOWS_STAT_TIMESPEC@
+//  struct timespec st_atim;
+//  struct timespec st_mtim;
+//  struct timespec st_ctim;
+////#  else
+////  time_t st_atime;
+////  time_t st_mtime;
+////  time_t st_ctime;
+////#  endif
+//};
+////#  if @WINDOWS_STAT_TIMESPEC@
+//#   define st_atime st_atim.tv_sec
+//#   define st_mtime st_mtim.tv_sec
+//#   define st_ctime st_ctim.tv_sec
+//    /* Indicator, for gnulib internal purposes.  */
+//#   define _GL_WINDOWS_STAT_TIMESPEC 1
+////#  endif
+//#  define GNULIB_defined_struct_stat 1
+//# endif
+
+#ifndef S_IFIFO
+# ifdef _S_IFIFO
+#  define S_IFIFO _S_IFIFO
+# endif
+#endif
+
+#ifndef S_IFMT
+# define S_IFMT 0170000
+#endif
+
+#if STAT_MACROS_BROKEN
+# undef S_ISBLK
+# undef S_ISCHR
+# undef S_ISDIR
+# undef S_ISFIFO
+# undef S_ISLNK
+# undef S_ISNAM
+# undef S_ISMPB
+# undef S_ISMPC
+# undef S_ISNWK
+# undef S_ISREG
+# undef S_ISSOCK
+#endif
+
+#ifndef S_ISBLK
+# ifdef S_IFBLK
+#  define S_ISBLK(m) (((m) & S_IFMT) == S_IFBLK)
+# else
+#  define S_ISBLK(m) 0
+# endif
+#endif
+
+#ifndef S_ISCHR
+# ifdef S_IFCHR
+#  define S_ISCHR(m) (((m) & S_IFMT) == S_IFCHR)
+# else
+#  define S_ISCHR(m) 0
+# endif
+#endif
+
+#ifndef S_ISDIR
+# ifdef S_IFDIR
+#  define S_ISDIR(m) (((m) & S_IFMT) == S_IFDIR)
+# else
+#  define S_ISDIR(m) 0
+# endif
+#endif
+
+#ifndef S_ISDOOR /* Solaris 2.5 and up */
+# define S_ISDOOR(m) 0
+#endif
+
+#ifndef S_ISFIFO
+# ifdef S_IFIFO
+#  define S_ISFIFO(m) (((m) & S_IFMT) == S_IFIFO)
+# else
+#  define S_ISFIFO(m) 0
+# endif
+#endif
+
+#ifndef S_ISLNK
+# ifdef S_IFLNK
+#  define S_ISLNK(m) (((m) & S_IFMT) == S_IFLNK)
+# else
+#  define S_ISLNK(m) 0
+# endif
+#endif
+
+#ifndef S_ISMPB /* V7 */
+# ifdef S_IFMPB
+#  define S_ISMPB(m) (((m) & S_IFMT) == S_IFMPB)
+#  define S_ISMPC(m) (((m) & S_IFMT) == S_IFMPC)
+# else
+#  define S_ISMPB(m) 0
+#  define S_ISMPC(m) 0
+# endif
+#endif
+
+#ifndef S_ISMPX /* AIX */
+# define S_ISMPX(m) 0
+#endif
+
+#ifndef S_ISNAM /* Xenix */
+# ifdef S_IFNAM
+#  define S_ISNAM(m) (((m) & S_IFMT) == S_IFNAM)
+# else
+#  define S_ISNAM(m) 0
+# endif
+#endif
+
+#ifndef S_ISNWK /* HP/UX */
+# ifdef S_IFNWK
+#  define S_ISNWK(m) (((m) & S_IFMT) == S_IFNWK)
+# else
+#  define S_ISNWK(m) 0
+# endif
+#endif
+
+#ifndef S_ISPORT /* Solaris 10 and up */
+# define S_ISPORT(m) 0
+#endif
+
+#ifndef S_ISREG
+# ifdef S_IFREG
+#  define S_ISREG(m) (((m) & S_IFMT) == S_IFREG)
+# else
+#  define S_ISREG(m) 0
+# endif
+#endif
+
+#ifndef S_ISSOCK
+# ifdef S_IFSOCK
+#  define S_ISSOCK(m) (((m) & S_IFMT) == S_IFSOCK)
+# else
+#  define S_ISSOCK(m) 0
+# endif
+#endif
+
+
+#ifndef S_TYPEISMQ
+# define S_TYPEISMQ(p) 0
+#endif
+
+#ifndef S_TYPEISTMO
+# define S_TYPEISTMO(p) 0
+#endif
+
+
+#ifndef S_TYPEISSEM
+# ifdef S_INSEM
+#  define S_TYPEISSEM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSEM)
+# else
+#  define S_TYPEISSEM(p) 0
+# endif
+#endif
+
+#ifndef S_TYPEISSHM
+# ifdef S_INSHD
+#  define S_TYPEISSHM(p) (S_ISNAM ((p)->st_mode) && (p)->st_rdev == S_INSHD)
+# else
+#  define S_TYPEISSHM(p) 0
+# endif
+#endif
+
+/* high performance ("contiguous data") */
+#ifndef S_ISCTG
+# define S_ISCTG(p) 0
+#endif
+
+/* Cray DMF (data migration facility): off line, with data  */
+#ifndef S_ISOFD
+# define S_ISOFD(p) 0
+#endif
+
+/* Cray DMF (data migration facility): off line, with no data  */
+#ifndef S_ISOFL
+# define S_ISOFL(p) 0
+#endif
+
+/* 4.4BSD whiteout */
+#ifndef S_ISWHT
+# define S_ISWHT(m) 0
+#endif
+
+/* If any of the following are undefined,
+   define them to their de facto standard values.  */
+#if !S_ISUID
+# define S_ISUID 04000
+#endif
+#if !S_ISGID
+# define S_ISGID 02000
+#endif
+
+/* S_ISVTX is a common extension to POSIX.  */
+#ifndef S_ISVTX
+# define S_ISVTX 01000
+#endif
+
+#if !S_IRUSR && S_IREAD
+# define S_IRUSR S_IREAD
+#endif
+#if !S_IRUSR
+# define S_IRUSR 00400
+#endif
+#if !S_IRGRP
+# define S_IRGRP (S_IRUSR >> 3)
+#endif
+#if !S_IROTH
+# define S_IROTH (S_IRUSR >> 6)
+#endif
+
+#if !S_IWUSR && S_IWRITE
+# define S_IWUSR S_IWRITE
+#endif
+#if !S_IWUSR
+# define S_IWUSR 00200
+#endif
+#if !S_IWGRP
+# define S_IWGRP (S_IWUSR >> 3)
+#endif
+#if !S_IWOTH
+# define S_IWOTH (S_IWUSR >> 6)
+#endif
+
+#if !S_IXUSR && S_IEXEC
+# define S_IXUSR S_IEXEC
+#endif
+#if !S_IXUSR
+# define S_IXUSR 00100
+#endif
+#if !S_IXGRP
+# define S_IXGRP (S_IXUSR >> 3)
+#endif
+#if !S_IXOTH
+# define S_IXOTH (S_IXUSR >> 6)
+#endif
+
+#if !S_IRWXU
+# define S_IRWXU (S_IRUSR | S_IWUSR | S_IXUSR)
+#endif
+#if !S_IRWXG
+# define S_IRWXG (S_IRGRP | S_IWGRP | S_IXGRP)
+#endif
+#if !S_IRWXO
+# define S_IRWXO (S_IROTH | S_IWOTH | S_IXOTH)
+#endif
+
+/* S_IXUGO is a common extension to POSIX.  */
+#if !S_IXUGO
+# define S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
+#endif
+
+#ifndef S_IRWXUGO
+# define S_IRWXUGO (S_IRWXU | S_IRWXG | S_IRWXO)
+#endif
+
+/* Macros for futimens and utimensat.  */
+#ifndef UTIME_NOW
+# define UTIME_NOW (-1)
+# define UTIME_OMIT (-2)
+#endif
+
+#if !HAVE_FCHMODAT
+extern int fchmodat(int fd, char const *file, mode_t mode, int flag);
+#endif
+
+
+#if !HAVE_FSTATAT
+extern int fstatat(int fd, char const *name, struct stat *st, int flags);
+#endif
+
+#if !HAVE_FUTIMENS
+extern int futimens(int fd, struct timespec const times[2]);
+#endif
+
+/* Change the mode of FILENAME to MODE, without dereferencing it if FILENAME
+   denotes a symbolic link.  */
+#if !HAVE_LCHMOD
+/* The lchmod replacement follows symbolic links.  Callers should take
+   this into account; lchmod should be applied only to arguments that
+   are known to not be symbolic links.  On hosts that lack lchmod,
+   this can lead to race conditions between the check and the
+   invocation of lchmod, but we know of no workarounds that are
+   reliable in general.  You might try requesting support for lchmod
+   from your operating system supplier.  */
+#define lchmod chmod
+#endif
+
+#if !HAVE_LSTAT
+/* mingw does not support symlinks, therefore it does not have lstat.  But
+   without links, stat does just fine.  */
+#define lstat stat
+#endif
+
+
+//#if @REPLACE_MKDIR@
+//# if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+//#  undef mkdir
+//#  define mkdir rpl_mkdir
+//# endif
+//_GL_FUNCDECL_RPL (mkdir, int, (char const *name, mode_t mode)
+//                              _GL_ARG_NONNULL ((1)));
+//_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode));
+//#else
+///* mingw's _mkdir() function has 1 argument, but we pass 2 arguments.
+//   Additionally, it declares _mkdir (and depending on compile flags, an
+//   alias mkdir), only in the nonstandard includes <direct.h> and <io.h>,
+//   which are included above.  */
+//# if defined _WIN32 && ! defined __CYGWIN__
+//
+//#  if !GNULIB_defined_rpl_mkdir
+//static int
+//rpl_mkdir (char const *name, mode_t mode)
+//{
+//  return _mkdir (name);
+//}
+//#   define GNULIB_defined_rpl_mkdir 1
+//#  endif
+//
+//#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+//#   define mkdir rpl_mkdir
+//#  endif
+//_GL_CXXALIAS_RPL (mkdir, int, (char const *name, mode_t mode));
+//# else
+//_GL_CXXALIAS_SYS (mkdir, int, (char const *name, mode_t mode));
+//# endif
+//#endif
+//_GL_CXXALIASWARN (mkdir);
+
+
+#if !HAVE_MKDIRAT
+extern int mkdirat(int fd, char const *file, mode_t mode);
+#endif
+
+#if !HAVE_MKFIFO
+extern int mkfifo(char const *file, mode_t mode);
+#endif
+
+#if !HAVE_MKFIFOAT
+extern int mkfifoat(int fd, char const *file, mode_t mode);
+#endif
+
+
+#if !HAVE_MKNOD
+extern int mknod(char const *file, mode_t mode, dev_t dev);
+#endif
+
+#if !HAVE_MKNODAT
+extern int mknodat(int fd, char const *file, mode_t mode, dev_t dev);
+#endif
+
+
+//#if @GNULIB_STAT@
+//# if @REPLACE_STAT@
+//#  if !@GNULIB_OVERRIDES_STRUCT_STAT@
+//    /* We can't use the object-like #define stat rpl_stat, because of
+//       struct stat.  This means that rpl_stat will not be used if the user
+//       does (stat)(a,b).  Oh well.  */
+//#   if defined _AIX && defined stat && defined _LARGE_FILES
+//     /* With _LARGE_FILES defined, AIX (only) defines stat to stat64,
+//        so we have to replace stat64() instead of stat(). */
+//#    undef stat64
+//#    define stat64(name, st) rpl_stat (name, st)
+//#   elif @WINDOWS_64_BIT_ST_SIZE@
+//     /* Above, we define stat to _stati64.  */
+//#    if defined __MINGW32__ && defined _stati64
+//#     ifndef _USE_32BIT_TIME_T
+//       /* The system headers define _stati64 to _stat64.  */
+//#      undef _stat64
+//#      define _stat64(name, st) rpl_stat (name, st)
+//#     endif
+//#    elif defined _MSC_VER && defined _stati64
+//#     ifdef _USE_32BIT_TIME_T
+//       /* The system headers define _stati64 to _stat32i64.  */
+//#      undef _stat32i64
+//#      define _stat32i64(name, st) rpl_stat (name, st)
+//#     else
+//       /* The system headers define _stati64 to _stat64.  */
+//#      undef _stat64
+//#      define _stat64(name, st) rpl_stat (name, st)
+//#     endif
+//#    else
+//#     undef _stati64
+//#     define _stati64(name, st) rpl_stat (name, st)
+//#    endif
+//#   elif defined __MINGW32__ && defined stat
+//#    ifdef _USE_32BIT_TIME_T
+//      /* The system headers define stat to _stat32i64.  */
+//#     undef _stat32i64
+//#     define _stat32i64(name, st) rpl_stat (name, st)
+//#    else
+//      /* The system headers define stat to _stat64.  */
+//#     undef _stat64
+//#     define _stat64(name, st) rpl_stat (name, st)
+//#    endif
+//#   elif defined _MSC_VER && defined stat
+//#    ifdef _USE_32BIT_TIME_T
+//      /* The system headers define stat to _stat32.  */
+//#     undef _stat32
+//#     define _stat32(name, st) rpl_stat (name, st)
+//#    else
+//      /* The system headers define stat to _stat64i32.  */
+//#     undef _stat64i32
+//#     define _stat64i32(name, st) rpl_stat (name, st)
+//#    endif
+//#   else /* !(_AIX || __MINGW32__ || _MSC_VER) */
+//#    undef stat
+//#    define stat(name, st) rpl_stat (name, st)
+//#   endif /* !_LARGE_FILES */
+//#  endif /* !@GNULIB_OVERRIDES_STRUCT_STAT@ */
+//_GL_EXTERN_C int stat (const char *name, struct stat *buf)
+//                      _GL_ARG_NONNULL ((1, 2));
+//# endif
+//#elif @GNULIB_OVERRIDES_STRUCT_STAT@
+///* see above:
+//  #define stat stat_used_without_requesting_gnulib_module_stat
+// */
+//#elif defined GNULIB_POSIXCHECK
+//# undef stat
+//# if HAVE_RAW_DECL_STAT
+//_GL_WARN_ON_USE (stat, "stat is unportable - "
+//                 "use gnulib module stat for portability");
+//# endif
+//#endif
+
+#if !HAVE_UTIMENSAT
+extern int utimensat(int fd, char const *name,
+                                   struct timespec const times[2], int flag);
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_SYS_STAT_H */
+
diff --git a/headers-mingw/sys_utsname.h b/headers-mingw/sys_utsname.h
new file mode 100644
index 0000000..c9733a7
--- /dev/null
+++ b/headers-mingw/sys_utsname.h
@@ -0,0 +1,80 @@
+/* Substitute for <sys/utsname.h>.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_SYS_UTSNAME_H
+#define _GL_SYS_UTSNAME_H
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Length of the entries in 'struct utsname' is 256.  */
+#define _UTSNAME_LENGTH 256
+
+#ifndef _UTSNAME_NODENAME_LENGTH
+# define _UTSNAME_NODENAME_LENGTH _UTSNAME_LENGTH
+#endif
+#ifndef _UTSNAME_SYSNAME_LENGTH
+# define _UTSNAME_SYSNAME_LENGTH _UTSNAME_LENGTH
+#endif
+#ifndef _UTSNAME_RELEASE_LENGTH
+# define _UTSNAME_RELEASE_LENGTH _UTSNAME_LENGTH
+#endif
+#ifndef _UTSNAME_VERSION_LENGTH
+# define _UTSNAME_VERSION_LENGTH _UTSNAME_LENGTH
+#endif
+#ifndef _UTSNAME_MACHINE_LENGTH
+# define _UTSNAME_MACHINE_LENGTH _UTSNAME_LENGTH
+#endif
+
+# if !GNULIB_defined_struct_utsname
+/* Structure describing the system and machine.  */
+struct utsname
+  {
+    /* Name of this node on the network.  */
+    char nodename[_UTSNAME_NODENAME_LENGTH];
+
+    /* Name of the implementation of the operating system.  */
+    char sysname[_UTSNAME_SYSNAME_LENGTH];
+    /* Current release level of this implementation.  */
+    char release[_UTSNAME_RELEASE_LENGTH];
+    /* Current version level of this release.  */
+    char version[_UTSNAME_VERSION_LENGTH];
+
+    /* Name of the hardware type the system is running on.  */
+    char machine[_UTSNAME_MACHINE_LENGTH];
+  };
+#  define GNULIB_defined_struct_utsname 1
+# endif
+
+# if !HAVE_UNAME
+extern int uname (struct utsname *buf);
+# endif
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_SYS_UTSNAME_H */
diff --git a/headers-mingw/sys_wait.h b/headers-mingw/sys_wait.h
new file mode 100644
index 0000000..c5a90af
--- /dev/null
+++ b/headers-mingw/sys_wait.h
@@ -0,0 +1,65 @@
+/* A POSIX-like <sys/wait.h>.
+   Copyright (C) 2001-2003, 2005-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_SYS_WAIT_H
+#define _GL_SYS_WAIT_H
+
+/* Get pid_t.  */
+#include <sys/types.h>
+
+
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+/* Native Windows API.  */
+
+#include <signal.h> /* for SIGTERM */
+
+/* The following macros apply to an argument x, that is a status of a process,
+   as returned by waitpid() or, equivalently, _cwait() or GetExitCodeProcess().
+   This value is simply an 'int', not composed of bit fields.  */
+
+/* When an unhandled fatal signal terminates a process, the exit code is 3.  */
+#define WIFSIGNALED(x) ((x) == 3)
+#define WIFEXITED(x) ((x) != 3)
+#define WIFSTOPPED(x) 0
+
+/* The signal that terminated a process is not known posthum.  */
+#define WTERMSIG(x) SIGTERM
+
+#define WEXITSTATUS(x) (x)
+
+/* There are no stopping signals.  */
+#define WSTOPSIG(x) 0
+
+/* There are no core dumps.  */
+#define WCOREDUMP(x) 0
+
+
+
+
+/* Declarations of functions.  */
+
+#if !HAVE_WAITPID
+/* dummy constants */
+#define WNOHANG (-1)
+#define WUNTRACED (-1)
+extern pid_t waitpid(pid_t pid, int *statusp, int options);
+#endif
+
+
+#endif /* _@GUARD_PREFIX@_SYS_WAIT_H */
diff --git a/headers-mingw/unistd.h b/headers-mingw/unistd.h
new file mode 100644
index 0000000..216d3b4
--- /dev/null
+++ b/headers-mingw/unistd.h
@@ -0,0 +1,566 @@
+/* Substitute for and wrapper around <unistd.h>.
+   Copyright (C) 2003-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+#ifndef _GL_UNISTD_H
+
+/* NetBSD 5.0 mis-defines NULL.  Also get size_t.  */
+#include <stddef.h>
+
+/* mingw doesn't define the SEEK_* or *_FILENO macros in <unistd.h>.  */
+/* MSVC declares 'unlink' in <stdio.h>, not in <unistd.h>.  We must include
+   it before we  #define unlink rpl_unlink.  */
+/* Cygwin 1.7.1 declares symlinkat in <stdio.h>, not in <unistd.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if (!(defined SEEK_CUR && defined SEEK_END && defined SEEK_SET) \
+     || (defined _WIN32 && ! defined __CYGWIN__) \
+     || defined __CYGWIN__) \
+    && ! defined __GLIBC__
+# include <stdio.h>
+#endif
+
+/* Cygwin 1.7.1 declares unlinkat in <fcntl.h>, not in <unistd.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if defined __CYGWIN__ \
+    && ! defined __GLIBC__
+# include <fcntl.h>
+#endif
+
+/* mingw fails to declare _exit in <unistd.h>.  */
+/* mingw, MSVC, BeOS, Haiku declare environ in <stdlib.h>, not in
+   <unistd.h>.  */
+/* Solaris declares getcwd not only in <unistd.h> but also in <stdlib.h>.  */
+/* OSF Tru64 Unix cannot see gnulib rpl_strtod when system <stdlib.h> is
+   included here.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if !defined __GLIBC__ && !defined __osf__
+# define __need_system_stdlib_h
+# include <stdlib.h>
+# undef __need_system_stdlib_h
+#endif
+
+/* Native Windows platforms declare chdir, getcwd, rmdir in
+   <io.h> and/or <direct.h>, not in <unistd.h>.
+   They also declare access(), chmod(), close(), dup(), dup2(), isatty(),
+   lseek(), read(), unlink(), write() in <io.h>.  */
+#if (defined _WIN32 && ! defined __CYGWIN__)
+# include <io.h>     /* mingw32, mingw64 */
+# include <direct.h> /* mingw64, MSVC 9 */
+#endif
+
+/* AIX and OSF/1 5.1 declare getdomainname in <netdb.h>, not in <unistd.h>.
+   NonStop Kernel declares gethostname in <netdb.h>, not in <unistd.h>.  */
+/* But avoid namespace pollution on glibc systems.  */
+#if ((defined _AIX || defined __osf__) \
+     || defined __TANDEM) \
+    && !defined __GLIBC__
+# include <netdb.h>
+#endif
+
+/* MSVC defines off_t in <sys/types.h>.
+   May also define off_t to a 64-bit type on native Windows.  */
+/* Get off_t.  */
+# include <sys/types.h>
+/* The definitions of _GL_FUNCDECL_RPL etc. are copied here.  */
+
+/* The definition of _GL_ARG_NONNULL is copied here.  */
+
+/* The definition of _GL_WARN_ON_USE is copied here.  */
+
+
+///* Get getopt(), optarg, optind, opterr, optopt.  */
+//#if @GNULIB_UNISTD_H_GETOPT@ && !defined _GL_SYSTEM_GETOPT
+//# include <getopt-cdefs.h>
+//# include <getopt-pfx-core.h>
+//#endif
+
+#ifndef _GL_UNISTD_INLINE
+# define _GL_UNISTD_INLINE _GL_INLINE
+#endif
+
+///* Hide some function declarations from <winsock2.h>.  */
+//
+//#if @GNULIB_GETHOSTNAME@ && @UNISTD_H_HAVE_WINSOCK2_H@
+//# if !defined _@GUARD_PREFIX@_SYS_SOCKET_H
+//#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+//#   undef socket
+//#   define socket              socket_used_without_including_sys_socket_h
+//#   undef connect
+//#   define connect             connect_used_without_including_sys_socket_h
+//#   undef accept
+//#   define accept              accept_used_without_including_sys_socket_h
+//#   undef bind
+//#   define bind                bind_used_without_including_sys_socket_h
+//#   undef getpeername
+//#   define getpeername         getpeername_used_without_including_sys_socket_h
+//#   undef getsockname
+//#   define getsockname         getsockname_used_without_including_sys_socket_h
+//#   undef getsockopt
+//#   define getsockopt          getsockopt_used_without_including_sys_socket_h
+//#   undef listen
+//#   define listen              listen_used_without_including_sys_socket_h
+//#   undef recv
+//#   define recv                recv_used_without_including_sys_socket_h
+//#   undef send
+//#   define send                send_used_without_including_sys_socket_h
+//#   undef recvfrom
+//#   define recvfrom            recvfrom_used_without_including_sys_socket_h
+//#   undef sendto
+//#   define sendto              sendto_used_without_including_sys_socket_h
+//#   undef setsockopt
+//#   define setsockopt          setsockopt_used_without_including_sys_socket_h
+//#   undef shutdown
+//#   define shutdown            shutdown_used_without_including_sys_socket_h
+//#  else
+//    _GL_WARN_ON_USE (socket,
+//                     "socket() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (connect,
+//                     "connect() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (accept,
+//                     "accept() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (bind,
+//                     "bind() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (getpeername,
+//                     "getpeername() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (getsockname,
+//                     "getsockname() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (getsockopt,
+//                     "getsockopt() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (listen,
+//                     "listen() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (recv,
+//                     "recv() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (send,
+//                     "send() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (recvfrom,
+//                     "recvfrom() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (sendto,
+//                     "sendto() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (setsockopt,
+//                     "setsockopt() used without including <sys/socket.h>");
+//    _GL_WARN_ON_USE (shutdown,
+//                     "shutdown() used without including <sys/socket.h>");
+//#  endif
+//# endif
+//# if !defined _@GUARD_PREFIX@_SYS_SELECT_H
+//#  if !(defined __cplusplus && defined GNULIB_NAMESPACE)
+//#   undef select
+//#   define select              select_used_without_including_sys_select_h
+//#  else
+//    _GL_WARN_ON_USE (select,
+//                     "select() used without including <sys/select.h>");
+//#  endif
+//# endif
+//#endif
+
+
+/* OS/2 EMX lacks these macros.  */
+#ifndef STDIN_FILENO
+# define STDIN_FILENO 0
+#endif
+#ifndef STDOUT_FILENO
+# define STDOUT_FILENO 1
+#endif
+#ifndef STDERR_FILENO
+# define STDERR_FILENO 2
+#endif
+
+/* Ensure *_OK macros exist.  */
+#ifndef F_OK
+# define F_OK 0
+# define X_OK 1
+# define W_OK 2
+# define R_OK 4
+#endif
+
+#ifndef MAXSYMLINKS
+# ifdef SYMLOOP_MAX
+#  define MAXSYMLINKS SYMLOOP_MAX
+# else
+#  define MAXSYMLINKS 20
+# endif
+#endif
+
+
+/* Declare overridden functions.  */
+
+/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
+   to GID (if GID is not -1).  Follow symbolic links.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/chown.html.  */
+#  if !HAVE_CHOWN
+extern int chown(const char *file, int uid, int gid);
+#  endif
+
+
+/* Copy the file descriptor OLDFD into file descriptor NEWFD.  Do nothing if
+   NEWFD = OLDFD, otherwise close NEWFD first if it is open.
+   Return newfd if successful, otherwise -1 and errno set.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/dup2.html>.  */
+#if !HAVE_DUP2
+extern int dup2(int oldfd, int newfd);
+#endif
+
+/* Copy the file descriptor OLDFD into file descriptor NEWFD, with the
+   specified flags.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   Close NEWFD first if it is open.
+   Return newfd if successful, otherwise -1 and errno set.
+   See the Linux man page at
+   <https://www.kernel.org/doc/man-pages/online/pages/man2/dup3.2.html>.  */
+#if !HAVE_DUP3
+extern int dup3(int oldfd, int newfd, int flags);
+#endif
+
+
+//#if @GNULIB_ENVIRON@
+//# if defined __CYGWIN__ && !defined __i386__
+///* The 'environ' variable is defined in a DLL. Therefore its declaration needs
+//   the '__declspec(dllimport)' attribute, but the system's <unistd.h> lacks it.
+//   This leads to a link error on 64-bit Cygwin when the option
+//   -Wl,--disable-auto-import is in use.  */
+//_GL_EXTERN_C __declspec(dllimport) char **environ;
+//# endif
+//# if !@HAVE_DECL_ENVIRON@
+///* Set of environment variables and values.  An array of strings of the form
+//   "VARIABLE=VALUE", terminated with a NULL.  */
+//#  if defined __APPLE__ && defined __MACH__
+//#   include <TargetConditionals.h>
+//#   if !TARGET_OS_IPHONE && !TARGET_IPHONE_SIMULATOR
+//#    define _GL_USE_CRT_EXTERNS
+//#   endif
+//#  endif
+//#  ifdef _GL_USE_CRT_EXTERNS
+//#   include <crt_externs.h>
+//#   define environ (*_NSGetEnviron ())
+//#  else
+//#   ifdef __cplusplus
+//extern "C" {
+//#   endif
+//extern char **environ;
+//#   ifdef __cplusplus
+//}
+//#   endif
+//#  endif
+//# endif
+//#elif defined GNULIB_POSIXCHECK
+//# if HAVE_RAW_DECL_ENVIRON
+//_GL_UNISTD_INLINE char ***
+//_GL_WARN_ON_USE_ATTRIBUTE ("environ is unportable - "
+//                           "use gnulib module environ for portability")
+//rpl_environ (void)
+//{
+//  return &environ;
+//}
+//#  undef environ
+//#  define environ (*rpl_environ ())
+//# endif
+//#endif
+
+
+/* Like access(), except that it uses the effective user id and group id of
+   the current process.  */
+# if !HAVE_EUIDACCESS
+extern int euidaccess(const char *filename, int mode);
+#endif
+
+
+#if !HAVE_FACCESSAT
+extern int faccessat(int fd, char const *file, int mode, int flag);
+#endif
+
+
+/* Change the process' current working directory to the directory on which
+   the given file descriptor is open.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fchdir.html>.  */
+#if !HAVE_FCHDIR
+extern int fchdir(int fd);
+
+/* Gnulib internal hooks needed to maintain the fchdir metadata.  */
+extern int _gl_register_fd (int fd, const char *filename);
+extern void _gl_unregister_fd (int fd);
+extern int _gl_register_dup (int oldfd, int newfd);
+extern const char *_gl_directory_name (int fd);
+#endif
+
+
+#if !HAVE_FCHOWNAT
+extern int fchownat(int fd, char const *file,
+                                  int owner, int group, int flag);
+#endif
+
+/* Synchronize changes to a file.
+   Return 0 if successful, otherwise -1 and errno set.
+   See POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fdatasync.html>.  */
+#if !HAVE_FDATASYNC
+extern int fdatasync(int fd);
+#endif
+
+/* Synchronize changes, including metadata, to a file.
+   Return 0 if successful, otherwise -1 and errno set.
+   See POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/fsync.html>.  */
+#if !HAVE_FSYNC
+extern int fsync(int fd);
+#endif
+
+/* Change the size of the file to which FD is opened to become equal to LENGTH.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/ftruncate.html>.  */
+#if !HAVE_FTRUNCATE
+extern int ftruncate(int fd, off_t length);
+#endif
+
+/* Return the NIS domain name of the machine.
+   WARNING! The NIS domain name is unrelated to the fully qualified host name
+            of the machine.  It is also unrelated to email addresses.
+   WARNING! The NIS domain name is usually the empty string or "(none)" when
+            not using NIS.
+
+   Put up to LEN bytes of the NIS domain name into NAME.
+   Null terminate it if the name is shorter than LEN.
+   If the NIS domain name is longer than LEN, set errno = EINVAL and return -1.
+   Return 0 if successful, otherwise set errno and return -1.  */
+#if !HAVE_GETDOMAINNAME
+extern int getdomainname(char *name, size_t len);
+#endif
+
+/* Return the maximum number of file descriptors in the current process.
+   In POSIX, this is same as sysconf (_SC_OPEN_MAX).  */
+#if !HAVE_GETDTABLESIZE
+extern int getdtablesize(void);
+#endif
+
+/* Return the supplemental groups that the current process belongs to.
+   It is unspecified whether the effective group id is in the list.
+   If N is 0, return the group count; otherwise, N describes how many
+   entries are available in GROUPS.  Return -1 and set errno if N is
+   not 0 and not large enough.  Fails with ENOSYS on some systems.  */
+#if !HAVE_GETGROUPS
+extern int getgroups(int n, int *groups);
+#endif
+
+/* Return the standard host name of the machine.
+   WARNING! The host name may or may not be fully qualified.
+
+   Put up to LEN bytes of the host name into NAME.
+   Null terminate it if the name is shorter than LEN.
+   If the host name is longer than LEN, set errno = EINVAL and return -1.
+   Return 0 if successful, otherwise set errno and return -1.  */
+#if !HAVE_GETHOSTNAME && !(defined _WIN32 && ! defined __CYGWIN__)
+extern int gethostname(char *name, size_t len);
+#endif
+
+/* Returns the user's login name, or NULL if it cannot be found.  Upon error,
+   returns NULL with errno set.
+
+   See <http://www.opengroup.org/susv3xsh/getlogin.html>.
+
+   Most programs don't need to use this function, because the information is
+   available through environment variables:
+     ${LOGNAME-$USER}        on Unix platforms,
+     $USERNAME               on native Windows platforms.
+ */
+# if !HAVE_GETLOGIN
+extern char * getlogin(void);
+#endif
+
+/* Copies the user's login name to NAME.
+   The array pointed to by NAME has room for SIZE bytes.
+
+   Returns 0 if successful.  Upon error, an error number is returned, or -1 in
+   the case that the login name cannot be found but no specific error is
+   provided (this case is hopefully rare but is left open by the POSIX spec).
+
+   See <http://www.opengroup.org/susv3xsh/getlogin.html>.
+
+   Most programs don't need to use this function, because the information is
+   available through environment variables:
+     ${LOGNAME-$USER}        on Unix platforms,
+     $USERNAME               on native Windows platforms.
+ */
+#if !HAVE_GETLOGIN_R
+extern int getlogin_r(char *name, size_t size);
+#endif
+
+
+/* Function getpass() from module 'getpass':
+     Read a password from /dev/tty or stdin.
+   Function getpass() from module 'getpass-gnu':
+     Read a password of arbitrary length from /dev/tty or stdin.  */
+#if !HAVE_GETPASS
+extern char * getpass(const char *prompt);
+#endif
+
+/* Return the next valid login shell on the system, or NULL when the end of
+   the list has been reached.  */
+#if !HAVE_GETUSERSHELL
+extern char * getusershell(void);
+#endif
+
+/* Rewind to pointer that is advanced at each getusershell() call.  */
+#if !HAVE_SETUSERSHELL
+extern void setusershell(void);
+#endif
+
+/* Free the pointer that is advanced at each getusershell() call and
+   associated resources.  */
+#if !HAVE_ENDUSERSHELL
+extern void endusershell(void);
+#endif
+
+/* Determine whether group id is in calling user's group list.  */
+#if !HAVE_GROUP_MEMBER
+extern int group_member(int gid);
+#endif
+
+/* Change the owner of FILE to UID (if UID is not -1) and the group of FILE
+   to GID (if GID is not -1).  Do not follow symbolic links.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/lchown.html>.  */
+#if !HAVE_LCHOWN
+extern int lchown(char const *file, int owner, int group);
+#endif
+
+/* Create a new hard link for an existing file.
+   Return 0 if successful, otherwise -1 and errno set.
+   See POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/link.html>.  */
+#if !HAVE_LINK
+extern int link(const char *path1, const char *path2);
+#endif
+
+/* Create a new hard link for an existing file, relative to two
+   directories.  FLAG controls whether symlinks are followed.
+   Return 0 if successful, otherwise -1 and errno set.  */
+#if !HAVE_LINKAT
+extern int linkat(int fd1, const char *path1, int fd2, const char *path2,
+                   int flag);
+#endif
+
+/* Create a pipe, defaulting to O_BINARY mode.
+   Store the read-end as fd[0] and the write-end as fd[1].
+   Return 0 upon success, or -1 with errno set upon failure.  */
+#if !HAVE_PIPE
+extern int pipe(int fd[2]);
+#endif
+
+/* Create a pipe, applying the given flags when opening the read-end of the
+   pipe and the write-end of the pipe.
+   The flags are a bitmask, possibly including O_CLOEXEC (defined in <fcntl.h>)
+   and O_TEXT, O_BINARY (defined in "binary-io.h").
+   Store the read-end as fd[0] and the write-end as fd[1].
+   Return 0 upon success, or -1 with errno set upon failure.
+   See also the Linux man page at
+   <https://www.kernel.org/doc/man-pages/online/pages/man2/pipe2.2.html>.  */
+#if !HAVE_PIPE2
+extern int pipe2(int fd[2], int flags);
+#endif
+
+/* Read at most BUFSIZE bytes from FD into BUF, starting at OFFSET.
+   Return the number of bytes placed into BUF if successful, otherwise
+   set errno and return -1.  0 indicates EOF.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/pread.html>.  */
+#if !HAVE_PREAD
+extern ssize_t pread(int fd, void *buf, size_t bufsize, off_t offset);
+#endif
+
+/* Write at most BUFSIZE bytes from BUF into FD, starting at OFFSET.
+   Return the number of bytes written if successful, otherwise
+   set errno and return -1.  0 indicates nothing written.  See the
+   POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/pwrite.html>.  */
+#if !HAVE_PWRITE
+extern ssize_t pwrite(int fd, const void *buf, size_t bufsize, off_t offset);
+#endif
+
+/* Read the contents of the symbolic link FILE and place the first BUFSIZE
+   bytes of it into BUF.  Return the number of bytes placed into BUF if
+   successful, otherwise -1 and errno set.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/readlink.html>.  */
+#if !HAVE_READLINK
+extern ssize_t readlink(const char *file, char *buf, size_t bufsize);
+#endif
+
+#if !HAVE_READLINKAT
+extern ssize_t readlinkat(int fd, char const *file, char *buf, size_t len);
+#endif
+
+/* Set the host name of the machine.
+   The host name may or may not be fully qualified.
+
+   Put LEN bytes of NAME into the host name.
+   Return 0 if successful, otherwise, set errno and return -1.
+
+   Platforms with no ability to set the hostname return -1 and set
+   errno = ENOSYS.  */
+#if !HAVE_SETHOSTNAME
+extern int sethostname(const char *name, size_t len);
+#endif
+
+/* Pause the execution of the current thread for N seconds.
+   Returns the number of seconds left to sleep.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/sleep.html>.  */
+#if !HAVE_SLEEP
+extern unsigned int sleep(unsigned int n);
+#endif
+
+#if !HAVE_SYMLINK
+extern int symlink(char const *contents, char const *file);
+#endif
+
+#if !HAVE_SYMLINKAT
+extern int symlinkat(char const *contents, int fd, char const *file);
+#endif
+
+/* Change the size of the file designated by FILENAME to become equal to LENGTH.
+   Return 0 if successful, otherwise -1 and errno set.
+   See the POSIX:2008 specification
+   <http://pubs.opengroup.org/onlinepubs/9699919799/functions/truncate.html>.  */
+#if !HAVE_TRUNCATE
+extern int truncate(const char *filename, off_t length);
+#endif
+
+/* Store at most BUFLEN characters of the pathname of the terminal FD is
+   open on in BUF.  Return 0 on success, otherwise an error number.  */
+#if !HAVE_TTYNAME_R
+extern int ttyname_r(int fd, char *buf, size_t buflen);
+#endif
+
+#if !HAVE_UNLINKAT
+extern int unlinkat(int fd, char const *file, int flag);
+#endif
+
+/* Pause the execution of the current thread for N microseconds.
+   Returns 0 on completion, or -1 on range error.
+   See the POSIX:2001 specification
+   <http://www.opengroup.org/susv3xsh/usleep.html>.  */
+#if !HAVE_USLEEP
+extern int usleep(useconds_t n);
+#endif
+
+#endif /* _@GUARD_PREFIX@_UNISTD_H */
+
diff --git a/install-sh b/install-sh
index a247329..8175c64 100755
--- a/install-sh
+++ b/install-sh
@@ -1,201 +1,518 @@
-:
-# NAME:
-#	install.sh - portable version of install(1)
-#
-# SYNOPSIS:
-#	install [-CNcs] [-f flags] [-i errs] [-o owner] [-g group] [-m mode] file1 file2 ...
-#	install -d  [-i errs] [-o owner] [-g group] [-m mode] directory ...
-#
-# DESCRIPTION:
-#	Compatible with BSD install(1).  Except that '-c' is always
-#	true and we always move an already installed target aside as
-#	this is important on many systems.  Recent BSD install(1)
-#	versions have a '-b' option for this.
-#
-#
-# OPTIONS:
-#	-b	move previous target file aside (always true).
+#!/bin/sh
+# install - install a program, script, or datafile
+
+scriptversion=2018-03-11.20; # UTC
+
+# This originates from X11R5 (mit/util/scripts/install.sh), which was
+# later released in X11R6 (xc/config/util/install.sh) with the
+# following copyright and license.
 #
-#	-B "suffix"
-#		use "suffix" instead of .old for saving existing target.
-#
-#	-c	copy rather than move the file into place (always true).
+# Copyright (C) 1994 X Consortium
 #
-#	-C	compare.  Only install if target is missing or
-#		different.
+# Permission is hereby granted, free of charge, to any person obtaining a copy
+# of this software and associated documentation files (the "Software"), to
+# deal in the Software without restriction, including without limitation the
+# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
+# sell copies of the Software, and to permit persons to whom the Software is
+# furnished to do so, subject to the following conditions:
 #
-#	-N	newer. Only install if target is missing or older.
-#
-#	-s	strip target
+# The above copyright notice and this permission notice shall be included in
+# all copies or substantial portions of the Software.
 #
-#	-o "owner"
-#		make target owned by "owner"
+# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE
+# X CONSORTIUM BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+# AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNEC-
+# TION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 #
-#	-g "group"
-#		make target group owned by "group"
+# Except as contained in this notice, the name of the X Consortium shall not
+# be used in advertising or otherwise to promote the sale, use or other deal-
+# ings in this Software without prior written authorization from the X Consor-
+# tium.
 #
-#	-m "mode"
-#		set permissions to "mode"
 #
-#	-f "flags"
-#		Pass "flags" onto chflags(1)
-#
-#	-i "errs"
-#		Ignore errors from steps indicated by "errs" (``s,o,g,m'').
+# FSF changes to this file are in the public domain.
 #
-# BUGS:
-#	The '-i' option is to save your sanity when 'bsd.prog.mk'
-#	insists on haveing a '-o' "owner" option which is doomed to
-#	fail on many systems.  We ignore '-b', '-B' and '-c' options.
-#
-# AUTHOR:
-#	Simon J. Gerraty <sjg@quick.com.au>
+# Calling this script install-sh is preferred over install.sh, to prevent
+# 'make' implicit rules from creating a file called install from it
+# when there is no Makefile.
 #
+# This script is compatible with the BSD install script, but was written
+# from scratch.

-# RCSid:
-#	$Id: install-sh,v 1.18 2001/03/16 17:33:02 sjg Exp $
-#
-#	@(#) Copyright (c) 1993 Simon J. Gerraty
-#
-#	This file is provided in the hope that it will
-#	be of use.  There is absolutely NO WARRANTY.
-#	Permission to copy, redistribute or otherwise
-#	use this file is hereby granted provided that
-#	the above copyright notice and this notice are
-#	left intact.
-#
-#	Please send copies of changes and bug-fixes to:
-#	sjg@quick.com.au
-#
+tab='	'
+nl='
+'
+IFS=" $tab$nl"

-set -- `getopt B:bpxCNcsdo:g:m:i:f: $*`
+# Set DOITPROG to "echo" to test this script.

-Mydir=`dirname $0`
-[ -s $Mydir/.installrc ] && . $Mydir/.installrc
+doit=${DOITPROG-}
+doit_exec=${doit:-exec}

-owner=:
-group=:
-mode=:
-strip=:
-mkdirs=
-compare=:
-newer=:
-chflags=:
-LS1=
-CP_P=
+# Put in absolute file names if you don't have them in your path;
+# or use environment vars.

-while [ $# -gt 1 ]
-do
-	case $1 in
-	--)	shift; break;;
-	-p)	CP_P=-p;;
-	-x)	set -x;;
-	-B)	OLD_EXT=$2; shift;;
-	-C)	compare=Different;;
-	-N)	newer=Newer;
-		# check if /bin/ls supports -1
-		/bin/ls -1 $0 >/dev/null 2>&1 && LS1=1
-		;;
-	-o)	owner="${CHOWN:-chown} $2 "; shift;;
-	-g)	group="${CHGRP:-chgrp} $2 "; shift;;
-	-m)	mode="${CHMOD:-chmod} $2 "; shift;;
-	-s)	strip=${STRIP:-strip};;
-	-d)	mkdirs="mkdir -p";;
-	-i)	ignore_err="$ignore_err$2"; shift;;
-	-f)	chflags="${CHFLAGS:-chflags} $2 "; shift;;
-	esac
-	shift
+chgrpprog=${CHGRPPROG-chgrp}
+chmodprog=${CHMODPROG-chmod}
+chownprog=${CHOWNPROG-chown}
+cmpprog=${CMPPROG-cmp}
+cpprog=${CPPROG-cp}
+mkdirprog=${MKDIRPROG-mkdir}
+mvprog=${MVPROG-mv}
+rmprog=${RMPROG-rm}
+stripprog=${STRIPPROG-strip}
+
+posix_mkdir=
+
+# Desired mode of installed file.
+mode=0755
+
+chgrpcmd=
+chmodcmd=$chmodprog
+chowncmd=
+mvcmd=$mvprog
+rmcmd="$rmprog -f"
+stripcmd=
+
+src=
+dst=
+dir_arg=
+dst_arg=
+
+copy_on_change=false
+is_target_a_directory=possibly
+
+usage="\
+Usage: $0 [OPTION]... [-T] SRCFILE DSTFILE
+   or: $0 [OPTION]... SRCFILES... DIRECTORY
+   or: $0 [OPTION]... -t DIRECTORY SRCFILES...
+   or: $0 [OPTION]... -d DIRECTORIES...
+
+In the 1st form, copy SRCFILE to DSTFILE.
+In the 2nd and 3rd, copy all SRCFILES to DIRECTORY.
+In the 4th, create DIRECTORIES.
+
+Options:
+     --help     display this help and exit.
+     --version  display version info and exit.
+
+  -c            (ignored)
+  -C            install only if different (preserve the last data modification time)
+  -d            create directories instead of installing files.
+  -g GROUP      $chgrpprog installed files to GROUP.
+  -m MODE       $chmodprog installed files to MODE.
+  -o USER       $chownprog installed files to USER.
+  -s            $stripprog installed files.
+  -t DIRECTORY  install into DIRECTORY.
+  -T            report an error if DSTFILE is a directory.
+
+Environment variables override the default commands:
+  CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG
+  RMPROG STRIPPROG
+"
+
+while test $# -ne 0; do
+  case $1 in
+    -c) ;;
+
+    -C) copy_on_change=true;;
+
+    -d) dir_arg=true;;
+
+    -g) chgrpcmd="$chgrpprog $2"
+        shift;;
+
+    --help) echo "$usage"; exit $?;;
+
+    -m) mode=$2
+        case $mode in
+          *' '* | *"$tab"* | *"$nl"* | *'*'* | *'?'* | *'['*)
+            echo "$0: invalid mode: $mode" >&2
+            exit 1;;
+        esac
+        shift;;
+
+    -o) chowncmd="$chownprog $2"
+        shift;;
+
+    -s) stripcmd=$stripprog;;
+
+    -t)
+        is_target_a_directory=always
+        dst_arg=$2
+        # Protect names problematic for 'test' and other utilities.
+        case $dst_arg in
+          -* | [=\(\)!]) dst_arg=./$dst_arg;;
+        esac
+        shift;;
+
+    -T) is_target_a_directory=never;;
+
+    --version) echo "$0 $scriptversion"; exit $?;;
+
+    --) shift
+        break;;
+
+    -*) echo "$0: invalid option: $1" >&2
+        exit 1;;
+
+    *)  break;;
+  esac
+  shift
 done

-Newer() {
-	n=`/bin/ls -t$LS1 $* 2>/dev/null | head -1`
-	[ $1 = $n ]
-}
-
-Different() {
-	cmp -s $*
-	[ $? != 0 ]
-}
-
-Err() {
-	case "$ignore_err" in
-	*$1*)	;;
-	*)	exit 1;;
-	esac
-}
-
-Setem() {
-	# the order is important
-	if [ ! -d $1 ]; then
-		$strip $1 || Err s
-	fi
-	$group $1 || Err g
-	$owner $1 || Err o
-	$mode  $1 || Err m
-	$chflags  $1 || Err f
-	return 0
-}
-
-# a bug in HP-UX's /bin/sh, means we need to re-set $*
-# after any calls to add_path()
-args="$*"
-
-# all this just for chown!
-add_path () { [ -d $1 ] && eval ${2:-PATH}="\$${2:-PATH}:$1"; }
-add_path /etc
-add_path /usr/etc
-add_path /sbin
-add_path /usr/sbin
-
-# restore saved $*
-set -- $args
-
-# make directories if needed
-# and ensure mode etc are as desired
-if [ "$mkdirs" ]; then
-	for d in $*
-	do
-		[ ! -d $d ] && $mkdirs $d
-		Setem $d
-	done
-	exit 0			# that's all we do
+# We allow the use of options -d and -T together, by making -d
+# take the precedence; this is for compatibility with GNU install.
+
+if test -n "$dir_arg"; then
+  if test -n "$dst_arg"; then
+    echo "$0: target directory not allowed when installing a directory." >&2
+    exit 1
+  fi
 fi

-# install files
-if [ $# -gt 2 ]; then
-	dest_dir=yes
-elif [ $# -eq 1 ]; then
-	echo "what should I do with $*?" >&2
-	exit 1
+if test $# -ne 0 && test -z "$dir_arg$dst_arg"; then
+  # When -d is used, all remaining arguments are directories to create.
+  # When -t is used, the destination is already specified.
+  # Otherwise, the last argument is the destination.  Remove it from $@.
+  for arg
+  do
+    if test -n "$dst_arg"; then
+      # $@ is not empty: it contains at least $arg.
+      set fnord "$@" "$dst_arg"
+      shift # fnord
+    fi
+    shift # arg
+    dst_arg=$arg
+    # Protect names problematic for 'test' and other utilities.
+    case $dst_arg in
+      -* | [=\(\)!]) dst_arg=./$dst_arg;;
+    esac
+  done
 fi

-# get list of files
-while [ $# -gt 1 ]
-do
-	files="$files $1"
-	shift
-done
-# last one is dest
-dest=$1
-shift
+if test $# -eq 0; then
+  if test -z "$dir_arg"; then
+    echo "$0: no input file specified." >&2
+    exit 1
+  fi
+  # It's OK to call 'install-sh -d' without argument.
+  # This can happen when creating conditional directories.
+  exit 0
+fi
+
+if test -z "$dir_arg"; then
+  if test $# -gt 1 || test "$is_target_a_directory" = always; then
+    if test ! -d "$dst_arg"; then
+      echo "$0: $dst_arg: Is not a directory." >&2
+      exit 1
+    fi
+  fi
+fi
+
+if test -z "$dir_arg"; then
+  do_exit='(exit $ret); exit $ret'
+  trap "ret=129; $do_exit" 1
+  trap "ret=130; $do_exit" 2
+  trap "ret=141; $do_exit" 13
+  trap "ret=143; $do_exit" 15

+  # Set umask so as not to create temps with too-generous modes.
+  # However, 'strip' requires both read and write access to temps.
+  case $mode in
+    # Optimize common cases.
+    *644) cp_umask=133;;
+    *755) cp_umask=22;;

-if [ "$dest_dir" = yes -a  ! -d $dest ]; then
-	echo "no directory $dest" >&2
-	exit 1
+    *[0-7])
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw='% 200'
+      fi
+      cp_umask=`expr '(' 777 - $mode % 1000 ')' $u_plus_rw`;;
+    *)
+      if test -z "$stripcmd"; then
+        u_plus_rw=
+      else
+        u_plus_rw=,u+rw
+      fi
+      cp_umask=$mode$u_plus_rw;;
+  esac
 fi

-for f in $files
+for src
 do
-	b=`basename $f`
-	if [ -d $dest ]; then
-		t=$dest/$b
-	else
-		t=$dest
-	fi
-	$newer $f $t || continue
-	$compare $f $t || continue
-	[ -f $t ] && { mv -f $t $t.old || exit 1; }
-	{ cp $CP_P $f $t && Setem $t; } || exit 1
+  # Protect names problematic for 'test' and other utilities.
+  case $src in
+    -* | [=\(\)!]) src=./$src;;
+  esac
+
+  if test -n "$dir_arg"; then
+    dst=$src
+    dstdir=$dst
+    test -d "$dstdir"
+    dstdir_status=$?
+  else
+
+    # Waiting for this to be detected by the "$cpprog $src $dsttmp" command
+    # might cause directories to be created, which would be especially bad
+    # if $src (and thus $dsttmp) contains '*'.
+    if test ! -f "$src" && test ! -d "$src"; then
+      echo "$0: $src does not exist." >&2
+      exit 1
+    fi
+
+    if test -z "$dst_arg"; then
+      echo "$0: no destination specified." >&2
+      exit 1
+    fi
+    dst=$dst_arg
+
+    # If destination is a directory, append the input filename.
+    if test -d "$dst"; then
+      if test "$is_target_a_directory" = never; then
+        echo "$0: $dst_arg: Is a directory" >&2
+        exit 1
+      fi
+      dstdir=$dst
+      dstbase=`basename "$src"`
+      case $dst in
+	*/) dst=$dst$dstbase;;
+	*)  dst=$dst/$dstbase;;
+      esac
+      dstdir_status=0
+    else
+      dstdir=`dirname "$dst"`
+      test -d "$dstdir"
+      dstdir_status=$?
+    fi
+  fi
+
+  case $dstdir in
+    */) dstdirslash=$dstdir;;
+    *)  dstdirslash=$dstdir/;;
+  esac
+
+  obsolete_mkdir_used=false
+
+  if test $dstdir_status != 0; then
+    case $posix_mkdir in
+      '')
+        # Create intermediate dirs using mode 755 as modified by the umask.
+        # This is like FreeBSD 'install' as of 1997-10-28.
+        umask=`umask`
+        case $stripcmd.$umask in
+          # Optimize common cases.
+          *[2367][2367]) mkdir_umask=$umask;;
+          .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;;
+
+          *[0-7])
+            mkdir_umask=`expr $umask + 22 \
+              - $umask % 100 % 40 + $umask % 20 \
+              - $umask % 10 % 4 + $umask % 2
+            `;;
+          *) mkdir_umask=$umask,go-w;;
+        esac
+
+        # With -d, create the new directory with the user-specified mode.
+        # Otherwise, rely on $mkdir_umask.
+        if test -n "$dir_arg"; then
+          mkdir_mode=-m$mode
+        else
+          mkdir_mode=
+        fi
+
+        posix_mkdir=false
+        case $umask in
+          *[123567][0-7][0-7])
+            # POSIX mkdir -p sets u+wx bits regardless of umask, which
+            # is incompatible with FreeBSD 'install' when (umask & 300) != 0.
+            ;;
+          *)
+            # Note that $RANDOM variable is not portable (e.g. dash);  Use it
+            # here however when possible just to lower collision chance.
+            tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$
+
+            trap 'ret=$?; rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null; exit $ret' 0
+
+            # Because "mkdir -p" follows existing symlinks and we likely work
+            # directly in world-writeable /tmp, make sure that the '$tmpdir'
+            # directory is successfully created first before we actually test
+            # 'mkdir -p' feature.
+            if (umask $mkdir_umask &&
+                $mkdirprog $mkdir_mode "$tmpdir" &&
+                exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1
+            then
+              if test -z "$dir_arg" || {
+                   # Check for POSIX incompatibilities with -m.
+                   # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or
+                   # other-writable bit of parent directory when it shouldn't.
+                   # FreeBSD 6.1 mkdir -m -p sets mode of existing directory.
+                   test_tmpdir="$tmpdir/a"
+                   ls_ld_tmpdir=`ls -ld "$test_tmpdir"`
+                   case $ls_ld_tmpdir in
+                     d????-?r-*) different_mode=700;;
+                     d????-?--*) different_mode=755;;
+                     *) false;;
+                   esac &&
+                   $mkdirprog -m$different_mode -p -- "$test_tmpdir" && {
+                     ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"`
+                     test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1"
+                   }
+                 }
+              then posix_mkdir=:
+              fi
+              rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir"
+            else
+              # Remove any dirs left behind by ancient mkdir implementations.
+              rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null
+            fi
+            trap '' 0;;
+        esac;;
+    esac
+
+    if
+      $posix_mkdir && (
+        umask $mkdir_umask &&
+        $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir"
+      )
+    then :
+    else
+
+      # The umask is ridiculous, or mkdir does not conform to POSIX,
+      # or it failed possibly due to a race condition.  Create the
+      # directory the slow way, step by step, checking for races as we go.
+
+      case $dstdir in
+        /*) prefix='/';;
+        [-=\(\)!]*) prefix='./';;
+        *)  prefix='';;
+      esac
+
+      oIFS=$IFS
+      IFS=/
+      set -f
+      set fnord $dstdir
+      shift
+      set +f
+      IFS=$oIFS
+
+      prefixes=
+
+      for d
+      do
+        test X"$d" = X && continue
+
+        prefix=$prefix$d
+        if test -d "$prefix"; then
+          prefixes=
+        else
+          if $posix_mkdir; then
+            (umask=$mkdir_umask &&
+             $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break
+            # Don't fail if two instances are running concurrently.
+            test -d "$prefix" || exit 1
+          else
+            case $prefix in
+              *\'*) qprefix=`echo "$prefix" | sed "s/'/'\\\\\\\\''/g"`;;
+              *) qprefix=$prefix;;
+            esac
+            prefixes="$prefixes '$qprefix'"
+          fi
+        fi
+        prefix=$prefix/
+      done
+
+      if test -n "$prefixes"; then
+        # Don't fail if two instances are running concurrently.
+        (umask $mkdir_umask &&
+         eval "\$doit_exec \$mkdirprog $prefixes") ||
+          test -d "$dstdir" || exit 1
+        obsolete_mkdir_used=true
+      fi
+    fi
+  fi
+
+  if test -n "$dir_arg"; then
+    { test -z "$chowncmd" || $doit $chowncmd "$dst"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dst"; } &&
+    { test "$obsolete_mkdir_used$chowncmd$chgrpcmd" = false ||
+      test -z "$chmodcmd" || $doit $chmodcmd $mode "$dst"; } || exit 1
+  else
+
+    # Make a couple of temp file names in the proper directory.
+    dsttmp=${dstdirslash}_inst.$$_
+    rmtmp=${dstdirslash}_rm.$$_
+
+    # Trap to clean up those temp files at exit.
+    trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0
+
+    # Copy the file name to the temp name.
+    (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") &&
+
+    # and set any options; do chmod last to preserve setuid bits.
+    #
+    # If any of these fail, we abort the whole thing.  If we want to
+    # ignore errors from any of these, just make sure not to ignore
+    # errors from the above "$doit $cpprog $src $dsttmp" command.
+    #
+    { test -z "$chowncmd" || $doit $chowncmd "$dsttmp"; } &&
+    { test -z "$chgrpcmd" || $doit $chgrpcmd "$dsttmp"; } &&
+    { test -z "$stripcmd" || $doit $stripcmd "$dsttmp"; } &&
+    { test -z "$chmodcmd" || $doit $chmodcmd $mode "$dsttmp"; } &&
+
+    # If -C, don't bother to copy if it wouldn't change the file.
+    if $copy_on_change &&
+       old=`LC_ALL=C ls -dlL "$dst"     2>/dev/null` &&
+       new=`LC_ALL=C ls -dlL "$dsttmp"  2>/dev/null` &&
+       set -f &&
+       set X $old && old=:$2:$4:$5:$6 &&
+       set X $new && new=:$2:$4:$5:$6 &&
+       set +f &&
+       test "$old" = "$new" &&
+       $cmpprog "$dst" "$dsttmp" >/dev/null 2>&1
+    then
+      rm -f "$dsttmp"
+    else
+      # Rename the file to the real destination.
+      $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null ||
+
+      # The rename failed, perhaps because mv can't rename something else
+      # to itself, or perhaps because mv is so ancient that it does not
+      # support -f.
+      {
+        # Now remove or move aside any old file at destination location.
+        # We try this two ways since rm can't unlink itself on some
+        # systems and the destination file might be busy for other
+        # reasons.  In this case, the final cleanup might fail but the new
+        # file should still install successfully.
+        {
+          test ! -f "$dst" ||
+          $doit $rmcmd -f "$dst" 2>/dev/null ||
+          { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null &&
+            { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; }
+          } ||
+          { echo "$0: cannot unlink or rename $dst" >&2
+            (exit 1); exit 1
+          }
+        } &&
+
+        # Now rename the file to the real destination.
+        $doit $mvcmd "$dsttmp" "$dst"
+      }
+    fi || exit 1
+
+    trap '' 0
+  fi
 done
-exit 0
+
+# Local variables:
+# eval: (add-hook 'before-save-hook 'time-stamp)
+# time-stamp-start: "scriptversion="
+# time-stamp-format: "%:y-%02m-%02d.%02H"
+# time-stamp-time-zone: "UTC0"
+# time-stamp-end: "; # UTC"
+# End:
diff --git a/job.c b/job.c
index ddf9d40..670798d 100644
--- a/job.c
+++ b/job.c
@@ -140,2 +140,5 @@ __RCSID("$NetBSD: job.c,v 1.195 2018/05/13 22:13:28 sjg Exp $");
 #include <sys/stat.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
 #include <sys/file.h>
@@ -146,13 +149,23 @@ __RCSID("$NetBSD: job.c,v 1.195 2018/05/13 22:13:28 sjg Exp $");
 #include <errno.h>
-#if !defined(USE_SELECT) && defined(HAVE_POLL_H)
-#include <poll.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+# include "headers-mingw/poll.h"
 #else
-#ifndef USE_SELECT			/* no poll.h */
-# define USE_SELECT
+# if !defined(USE_SELECT) && defined(HAVE_POLL_H)
+#  include <poll.h>
+# else
+#  ifndef USE_SELECT			/* no poll.h */
+#   define USE_SELECT
+#  endif
+# endif
+# if defined(HAVE_SYS_SELECT_H)
+#  include <sys/select.h>
+# endif
 #endif
-#if defined(HAVE_SYS_SELECT_H)
-# include <sys/select.h>
+#include <signal.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/signal.h"
 #endif
+#ifndef SIGQUIT
+#define SIGQUIT SIGTERM
 #endif
-#include <signal.h>
 #include <stdio.h>
@@ -315,4 +328,8 @@ const char *shellPath = NULL,		  	  /* full pathname of
 char *shellErrFlag = NULL;
-static const char *shellArgv = NULL;		  /* Custom shell args */

+#if (defined _WIN32 && ! defined __CYGWIN__)
+const char *shellExecCmd = NULL;
+#endif
+
+static const char *shellArgv = NULL;		  /* Custom shell args */

@@ -439,2 +456,3 @@ JobCreatePipe(Job *job, int minfd)
     /* Set close-on-exec flag for both */
+#if defined(F_SETFD) && defined(FD_CLOEXEC) && defined(F_GETFL) && defined(F_SETFL)
     if (fcntl(job->jobPipe[0], F_SETFD, FD_CLOEXEC) == -1)
@@ -456,2 +474,3 @@ JobCreatePipe(Job *job, int minfd)
 	Punt("Cannot set flags: %s", strerror(errno));
+#endif
 }
@@ -1115,3 +1134,3 @@ JobFinish (Job *job, WAIT_T status)
 	}
-	job->node->made = MADE;
+	job->node->made = __MADE;
 	if (!(job->flags & JOB_SPECIAL))
@@ -1386,2 +1405,3 @@ JobExec(Job *job, char **argv)
 	}
+#if defined(F_SETFD)
 	if (fcntl(0, F_SETFD, 0) == -1) {
@@ -1390,2 +1410,3 @@ JobExec(Job *job, char **argv)
 	}
+#endif
 	if (lseek(0, (off_t)0, SEEK_SET) == -1) {
@@ -1394,3 +1415,3 @@ JobExec(Job *job, char **argv)
 	}
-
+#if defined(F_SETFD)
 	if (job->node->type & (OP_MAKE | OP_SUBMAKE)) {
@@ -1408,2 +1429,3 @@ JobExec(Job *job, char **argv)
 	}
+#endif

@@ -1423,2 +1445,3 @@ JobExec(Job *job, char **argv)
 	 */
+#if defined(F_SETFD)
 	if (fcntl(1, F_SETFD, 0) == -1) {
@@ -1427,2 +1450,3 @@ JobExec(Job *job, char **argv)
 	}
+#endif
 	if (dup2(1, 2) == -1) {
@@ -1439,9 +1463,7 @@ JobExec(Job *job, char **argv)
 	(void)setpgid(0, getpid());
-#else
-#if defined(HAVE_SETSID)
+#elif defined(HAVE_SETSID)
 	/* XXX: dsl - I'm sure this should be setpgrp()... */
 	(void)setsid();
-#else
+#elif defined(HAVE_SETPGRP)
 	(void)setpgrp(0, getpid());
-#endif
 #endif
@@ -1642,3 +1664,5 @@ JobStart(GNode *gn, int flags)
 	}
+#if defined(F_SETFD)
 	(void)fcntl(FILENO(job->cmdFILE), F_SETFD, FD_CLOEXEC);
+#endif
 	/*
@@ -1734,3 +1758,3 @@ JobStart(GNode *gn, int flags)
 	    }
-	    job->node->made = MADE;
+	    job->node->made = __MADE;
 	    Make_Update(job->node);
@@ -1983,3 +2007,3 @@ JobRun(GNode *targ)
     Compat_Make(targ, targ);
-    if (targ->made == ERROR) {
+    if (targ->made == __ERROR) {
 	PrintOnError(targ, "\n\nStop.");
@@ -2063,2 +2087,3 @@ JobReapChild(pid_t pid, WAIT_T status, Boolean isJobs)
 	    switch (WSTOPSIG(status)) {
+#if defined(SIGTSTP)
 	    case SIGTSTP:
@@ -2066,2 +2091,3 @@ JobReapChild(pid_t pid, WAIT_T status, Boolean isJobs)
 		break;
+#endif
 	    case SIGSTOP:
@@ -2191,2 +2217,7 @@ Shell_Init(void)
     }
+#if (defined _WIN32 && ! defined __CYGWIN__)
+    if (shellExecCmd == NULL) {
+        shellExecCmd = getShellLaunchPrefix();
+    }
+#endif
     if (commandShell->exit == NULL) {
@@ -2301,2 +2332,3 @@ Job_Init(void)
     sigemptyset(&caught_signals);
+#if defined(SIGCHLD)
     /*
@@ -2306,2 +2338,3 @@ Job_Init(void)
     sigaddset(&caught_signals, SIGCHLD);
+#endif

@@ -2318,3 +2351,5 @@ Job_Init(void)
     ADDSIG(SIGINT, JobPassSig_int)
+#if defined(SIGHUP)
     ADDSIG(SIGHUP, JobPassSig_term)
+#endif
     ADDSIG(SIGTERM, JobPassSig_term)
@@ -2328,7 +2363,17 @@ Job_Init(void)
      */
+#if defined(SIGTSTP)
     ADDSIG(SIGTSTP, JobPassSig_suspend)
+#endif
+#if defined(SIGTTOU)
     ADDSIG(SIGTTOU, JobPassSig_suspend)
+#endif
+#if defined(SIGTTIN)
     ADDSIG(SIGTTIN, JobPassSig_suspend)
+#endif
+#if defined(SIGWINCH)
     ADDSIG(SIGWINCH, JobCondPassSig)
+#endif
+#if defined(SIGCONT)
     ADDSIG(SIGCONT, JobContinueSig)
+#endif
 #undef ADDSIG
@@ -2347,12 +2392,26 @@ static void JobSigReset(void)
     DELSIG(SIGINT)
+#if defined(SIGHUP)
     DELSIG(SIGHUP)
+#endif
     DELSIG(SIGQUIT)
     DELSIG(SIGTERM)
+#if defined(SIGTSTP)
     DELSIG(SIGTSTP)
+#endif
+#if defined(SIGTTOU)
     DELSIG(SIGTTOU)
+#endif
+#if defined(SIGTTIN)
     DELSIG(SIGTTIN)
+#endif
+#if defined(SIGWINCH)
     DELSIG(SIGWINCH)
+#endif
+#if defined(SIGCONT)
     DELSIG(SIGCONT)
+#endif
 #undef DELSIG
+#if defined(SIGCHLD)
     (void)bmake_signal(SIGCHLD, SIG_DFL);
+#endif
 }
@@ -2791,2 +2850,3 @@ JobRestartJobs(void)
 	    job->job_suspended = 0;
+#if defined(SIGCONT)
 	    if (KILLPG(job->pid, SIGCONT) != 0 && DEBUG(JOB)) {
@@ -2794,2 +2854,3 @@ JobRestartJobs(void)
 	    }
+#endif
 	}
@@ -2888,4 +2949,6 @@ Job_ServerStart(int max_tokens, int jp_0, int jp_1)
 	tokenWaitJob.outPipe = jp_1;
+#if defined(F_SETFD)
 	(void)fcntl(jp_0, F_SETFD, FD_CLOEXEC);
 	(void)fcntl(jp_1, F_SETFD, FD_CLOEXEC);
+#endif
 	return;
@@ -3022,3 +3085,3 @@ Job_RunTarget(const char *target, const char *fname) {
     JobRun(gn);
-    if (gn->made == ERROR) {
+    if (gn->made == __ERROR) {
 	PrintOnError(gn, "\n\nStop.");
diff --git a/job.h b/job.h
index 91e2c87..ca8e093 100644
--- a/job.h
+++ b/job.h
@@ -246,2 +246,5 @@ extern const char *shellName;
 extern char *shellErrFlag;
+#if (defined _WIN32 && ! defined __CYGWIN__)
+extern const char *shellExecCmd;
+#endif

diff --git a/main.c b/main.c
index 7dd4c50..76e319e 100644
--- a/main.c
+++ b/main.c
@@ -118,4 +118,11 @@ __RCSID("$NetBSD: main.c,v 1.273 2017/10/28 21:54:54 sjg Exp $");
 #include <sys/param.h>
+#ifdef HAVE_SYS_RESOURCE_H
 #include <sys/resource.h>
+#else
+#include "headers-mingw/resource.h"
+#endif
 #include <sys/stat.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
 #if defined(MAKE_NATIVE) && defined(HAVE_SYSCTL)
@@ -123,3 +130,8 @@ __RCSID("$NetBSD: main.c,v 1.273 2017/10/28 21:54:54 sjg Exp $");
 #endif
+
+#ifdef HAVE_SYS_UTSNAME_H
 #include <sys/utsname.h>
+#else
+#include "headers-mingw/sys_utsname.h"
+#endif
 #include "wait.h"
@@ -128,2 +140,8 @@ __RCSID("$NetBSD: main.c,v 1.273 2017/10/28 21:54:54 sjg Exp $");
 #include <signal.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/signal.h"
+#endif
+#ifndef SIGQUIT
+#define SIGQUIT SIGTERM
+#endif
 #include <stdarg.h>
@@ -131,2 +149,5 @@ __RCSID("$NetBSD: main.c,v 1.273 2017/10/28 21:54:54 sjg Exp $");
 #include <stdlib.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/stdlib.h"
+#endif
 #include <time.h>
@@ -141,2 +162,6 @@ __RCSID("$NetBSD: main.c,v 1.273 2017/10/28 21:54:54 sjg Exp $");

+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include <process.h>
+#endif
+
 #ifdef USE_IOVEC
@@ -153,2 +178,4 @@ __RCSID("$NetBSD: main.c,v 1.273 2017/10/28 21:54:54 sjg Exp $");

+FILE *debug_file;		/* Output written here - default stdout */
+
 Lst			create;		/* Targets to be made */
@@ -196,2 +223,4 @@ static char objdir[MAXPATHLEN + 1];	/* where we chdir'ed to */
 char curdir[MAXPATHLEN + 1];		/* Startup directory */
+char *pcurdir;
+char *pobjdir;
 char *progname;				/* the program name */
@@ -764,3 +793,3 @@ Main_SetObjdir(const char *fmt, ...)

-	if (path[0] != '/') {
+	if (path[0] != '/' && curdir[0] == '/') { //because directory path could start not from '/' (example: Windows OS family)
 		snprintf(buf2, MAXPATHLEN, "%s/%s", curdir, path);
@@ -776,4 +805,13 @@ Main_SetObjdir(const char *fmt, ...)
 			strncpy(objdir, path, MAXPATHLEN);
-			Var_Set(".OBJDIR", objdir, VAR_GLOBAL, 0);
-			setenv("PWD", objdir, 1);
+#if (defined _WIN32 && ! defined __CYGWIN__)
+            pobjdir = str_replace_char(objdir, '\\', '/');
+            if (pobjdir[1] == ':') { // create msys-style windows path
+                pobjdir[1] = pobjdir[0];
+                pobjdir[0] = '/';
+            }
+#else
+            pobjdir = objdir;
+#endif
+			Var_Set(".OBJDIR", pobjdir, VAR_GLOBAL, 0);
+			setenv("PWD", pobjdir, 1);
 			Dir_InitDot();
@@ -990,2 +1028,4 @@ main(int argc, char **argv)
 	char mdpath[MAXPATHLEN];
+    const char *error;
+
 #ifdef FORCE_MACHINE
@@ -1017,3 +1057,9 @@ main(int argc, char **argv)
 	srandom(rightnow.tv_sec + rightnow.tv_usec);
-
+
+#if (defined _WIN32 && ! defined __CYGWIN__)
+    if ((progname = strrchr(argv[0], '\\')) != NULL)
+		progname++;
+	else
+		progname = argv[0];
+#else
 	if ((progname = strrchr(argv[0], '/')) != NULL)
@@ -1022,3 +1068,4 @@ main(int argc, char **argv)
 		progname = argv[0];
-#if defined(MAKE_NATIVE) || (defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE))
+#endif
+#if defined(HAVE_SETRLIMIT) && defined(RLIMIT_NOFILE)
 	/*
@@ -1165,2 +1212,11 @@ main(int argc, char **argv)
 	}
+
+#if (defined _WIN32 && ! defined __CYGWIN__)
+//    p1 = str_replace_char(p1, '\\', '/');
+//	if (p1[1] == ':') { // create msys-style windows path
+//	    p1[1] = p1[0];
+//	    p1[0] = '/';
+//	}
+p1 = Cmd_Exec(getUnixPathCmd(p1), &error);
+#endif
 	Var_Set("MAKE", p1, VAR_GLOBAL, 0);
@@ -1187,4 +1243,6 @@ main(int argc, char **argv)
 	    Var_Set(".MAKE.PID", tmp, VAR_GLOBAL, 0);
+#ifdef HAVE_GETPPID
 	    snprintf(tmp, sizeof(tmp), "%u", getppid());
 	    Var_Set(".MAKE.PPID", tmp, VAR_GLOBAL, 0);
+#endif
 	}
@@ -1269,3 +1327,13 @@ main(int argc, char **argv)
 #endif
-	Var_Set(".CURDIR", curdir, VAR_GLOBAL, 0);
+#if (defined _WIN32 && ! defined __CYGWIN__)
+//    pcurdir = str_replace_char(curdir, '\\', '/');
+//	if (pcurdir[1] == ':') { // create msys-style windows path
+//	    pcurdir[1] = pcurdir[0];
+//	    pcurdir[0] = '/';
+//	}
+pcurdir = Cmd_Exec(getUnixPathCmd(curdir), &error);
+#else
+	pcurdir = curdir;
+#endif
+	Var_Set(".CURDIR", pcurdir, VAR_GLOBAL, 0);

@@ -1607,4 +1675,2 @@ found:

-
-
 /*-
@@ -1625,3 +1691,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
     const char	*args[4];   	/* Args for invoking the shell */
+#if !(defined _WIN32 && ! defined __CYGWIN__)
     int 	fds[2];	    	/* Pipe streams */
+#else
+	FILE * fds[2];
+#endif
     int 	cpid;	    	/* Child PID */
@@ -1629,4 +1699,16 @@ Cmd_Exec(const char *cmd, const char **errnum)
     char	*res;		/* result */
+#if !(defined _WIN32 && ! defined __CYGWIN__)
     WAIT_T	status;		/* command exit status */
     Buffer	buf;		/* buffer to store the result */
+#else
+    const char *sysRootPath = getenv("SYSROOTWINDOWSPATH");
+    int status;
+    char command[4096] = ""; /* generated cmd string for launch */
+    char escapedCmd[4096] = "";
+    char escapedCmdLaunchList[4096] = ""; /* temporary string */
+    static char stdout_data[16 * 1024 * 1024] = ""; //stdout
+    static char stderr_data[16 * 1024 * 1024] = "";
+    int exit_code = 0;
+#endif
+
     char	*cp;
@@ -1636,2 +1718,3 @@ Cmd_Exec(const char *cmd, const char **errnum)

+
     *errnum = NULL;
@@ -1643,4 +1726,10 @@ Cmd_Exec(const char *cmd, const char **errnum)
      */
+#if !(defined _WIN32 && ! defined __CYGWIN__)
     args[0] = shellName;
     args[1] = "-c";
+#else
+    args[0] = str_concat(sysRootPath, "usr\\bin\\bash.exe", 0);
+    args[1] = "-lc";
+#endif
+
     args[2] = cmd;
@@ -1648,2 +1737,3 @@ Cmd_Exec(const char *cmd, const char **errnum)

+#if !(defined _WIN32 && ! defined __CYGWIN__)
     /*
@@ -1656,2 +1746,3 @@ Cmd_Exec(const char *cmd, const char **errnum)

+
     /*
@@ -1661,2 +1752,3 @@ Cmd_Exec(const char *cmd, const char **errnum)
     case 0:
+
 	/*
@@ -1673,5 +1765,7 @@ Cmd_Exec(const char *cmd, const char **errnum)
 	(void)close(fds[1]);
-
+#endif
 	Var_ExportVars();

+#if !(defined _WIN32 && ! defined __CYGWIN__)
+
 	(void)execv(shellPath, UNCONST(args));
@@ -1685,7 +1779,41 @@ Cmd_Exec(const char *cmd, const char **errnum)
     default:
-	/*
-	 * No need for the writing half
-	 */
-	(void)close(fds[1]);
+        /*
+ * No need for the writing half
+ */
+        (void)close(fds[1]);
+#else
+//      str_escape(escapedCmd, args[2], 4096);
+//      strncpy(command, str_concat(shellExecCmd,
+//      		str_concat("\"",
+//      				str_concat(str_concat(args[0],
+//                                      str_concat(args[1],
+//                                      		str_concat("'",
+//      											str_concat(escapedCmd, "'", 0),
+//      										0),
+//      										STR_ADDSPACE),
+//                                      STR_ADDSPACE), "\"", 0),
+//      				0),
+//      				STR_ADDSPACE), 4096);
+//      fds[0] = _popen(command, "rb");
+//      if (fds[0] == NULL) {
+//      	savederr = errno;
+//      }
+        str_escape_dblquote(escapedCmd, cmd, 4096);
+        strncpy(command,
+//      		str_concat("\"",
+//      				str_concat(
+      				        str_concat(args[0],
+                                      str_concat(args[1],
+                                      		str_concat("\"",
+      											str_concat(escapedCmd, "\"", 0),
+      										0),
+      										STR_ADDSPACE),
+                                      STR_ADDSPACE),
+//                                    , "\"", 0),
+//     				0),
+      				4096);
+        status = system_np(command, 100 * 1000, stdout_data, sizeof(stdout_data), stderr_data, sizeof(stderr_data), &exit_code);
+#endif

+#if !(defined _WIN32 && ! defined __CYGWIN__)
 	savederr = 0;
@@ -1715,2 +1843,3 @@ Cmd_Exec(const char *cmd, const char **errnum)
 	}
+
 	cc = Buf_Size(&buf);
@@ -1720,7 +1849,16 @@ Cmd_Exec(const char *cmd, const char **errnum)
 	    *errnum = "Couldn't read shell's output for \"%s\"";
+#else
+    cc = strlen(stdout_data);
+    res = bmake_malloc(cc + 1);
+	strncpy(res, stdout_data, cc);
+#endif

+#if !(defined _WIN32 && ! defined __CYGWIN__)
 	if (WIFSIGNALED(status))
 	    *errnum = "\"%s\" exited on a signal";
-	else if (WEXITSTATUS(status) != 0)
+	else if (WEXITSTATUS(status) != 0) {
+
 	    *errnum = "\"%s\" returned non-zero status";
+    }
+#endif

@@ -1745,4 +1883,6 @@ Cmd_Exec(const char *cmd, const char **errnum)
 	}
+#if !(defined _WIN32 && ! defined __CYGWIN__)
 	break;
     }
+#endif
     return res;
@@ -2118,3 +2258,4 @@ getTmpdir(void)
 	 */
-	tmpdir = Var_Subst(NULL, "${TMPDIR:tA:U" _PATH_TMP "}/", VAR_GLOBAL,
+	tmpdir = Var_Subst(NULL, str_concat(
+                str_concat("${TMPDIR:tA:U", _PATH_TMP, 0), "}/", 0), VAR_GLOBAL,
 			   VARF_WANTRES);
diff --git a/make-bootstrap.sh.in b/make-bootstrap.sh.in
index a394272..f74bc72 100755
--- a/make-bootstrap.sh.in
+++ b/make-bootstrap.sh.in
@@ -24,2 +24,13 @@ LDFLAGS="@LDFLAGS@"
 LIBS="@LIBS@"
+MACHINE="@machine@"
+
+if [ "$(expr substr ${MACHINE} 1 5)" == "mingw" ]; then
+    LIBS+=" -lws2_32 -lwsock32"
+    CFLAGS+=""
+fi
+
+if [ "$(expr substr ${MACHINE} 1 7)" == "mingw32" ]; then
+    LIBS+=" -liconv -lkernel32"
+    CFLAGS+=""
+fi

diff --git a/make.1 b/make.1
index 2a2237f..968f006 100644
--- a/make.1
+++ b/make.1
@@ -1927,3 +1927,3 @@ as if they all were preceded by a dash
 .\" XXX
-.It Ic .MADE
+.It Ic .__MADE
 Mark all sources of this target as being up-to-date.
@@ -2089,3 +2089,3 @@ Any command lines attached to this target are executed after everything
 else is done.
-.It Ic .ERROR
+.It Ic .__ERROR
 Any command lines attached to this target are executed when another target fails.
diff --git a/make.c b/make.c
index 8947582..796202c 100644
--- a/make.c
+++ b/make.c
@@ -703,3 +703,3 @@ Make_Update(GNode *cgn)
      */
-    if (cgn->made != UPTODATE) {
+    if (cgn->made != __UPTODATE) {
 	mtime = Make_Recheck(cgn);
@@ -759,3 +759,3 @@ Make_Update(GNode *cgn)
 	    if ( ! (cgn->type & (OP_EXEC|OP_USE|OP_USEBEFORE))) {
-		if (cgn->made == MADE)
+		if (cgn->made == __MADE)
 		    pgn->flags |= CHILDMADE;
@@ -768,3 +768,3 @@ Make_Update(GNode *cgn)
 	     */
-	    if (centurion->unmade_cohorts != 0 || centurion->made < MADE) {
+	    if (centurion->unmade_cohorts != 0 || centurion->made < __MADE) {
 		if (DEBUG(MAKE))
@@ -794,3 +794,3 @@ Make_Update(GNode *cgn)
 	    }
-	    if (pgn->made != DEFERRED) {
+	    if (pgn->made != __DEFERRED) {
 		/*
@@ -817,3 +817,3 @@ Make_Update(GNode *cgn)
 	    /* Ok, we can schedule the parent again */
-	    pgn->made = REQUESTED;
+	    pgn->made = __REQUESTED;
 	    (void)Lst_EnQueue(toBeMade, pgn);
@@ -908,3 +908,3 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
 	if (pgn->type & OP_JOIN) {
-	    if (cgn->made == MADE) {
+	    if (cgn->made == __MADE) {
 		Var_Append(OODATE, child, pgn);
@@ -912,3 +912,3 @@ MakeAddAllSrc(void *cgnp, void *pgnp)
 	} else if ((pgn->mtime < cgn->mtime) ||
-		   (cgn->mtime >= now && cgn->made == MADE))
+		   (cgn->mtime >= now && cgn->made == __MADE))
 	{
@@ -1005,3 +1005,3 @@ MakeCheckOrder(void *v_bn, void *ignore MAKE_ATTR_UNUSED)

-    if (bn->made >= MADE || !(bn->flags & REMAKE))
+    if (bn->made >= __MADE || !(bn->flags & REMAKE))
 	return 0;
@@ -1021,3 +1021,3 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
 	    cn->name, cn->cohort_num, cn->made, cn->type);
-    if (cn->made > DEFERRED)
+    if (cn->made > __DEFERRED)
 	return 0;
@@ -1027,3 +1027,3 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)
 	/* Can't build this (or anything else in this child list) yet */
-	cn->made = DEFERRED;
+	cn->made = __DEFERRED;
 	return 0;			/* but keep looking */
@@ -1035,3 +1035,3 @@ MakeBuildChild(void *v_cn, void *toBeMade_next)

-    cn->made = REQUESTED;
+    cn->made = __REQUESTED;
     if (toBeMade_next == NULL)
@@ -1057,3 +1057,3 @@ MakeBuildParent(void *v_pn, void *toBeMade_next)

-    if (pn->made != DEFERRED)
+    if (pn->made != __DEFERRED)
 	return 0;
@@ -1085,3 +1085,3 @@ MakeStartJobs(void)

-	if (gn->made != REQUESTED) {
+	if (gn->made != __REQUESTED) {
 	    if (DEBUG(MAKE))
@@ -1097,3 +1097,3 @@ MakeStartJobs(void)
 			gn->name, gn->cohort_num);
-	    gn->made = DEFERRED;
+	    gn->made = __DEFERRED;
 	    continue;
@@ -1107,3 +1107,3 @@ MakeStartJobs(void)
 	     */
-	    gn->made = DEFERRED;
+	    gn->made = __DEFERRED;
 	    Lst_ForEach(gn->children, MakeBuildChild, Lst_First(toBeMade));
@@ -1115,3 +1115,3 @@ MakeStartJobs(void)

-	gn->made = BEINGMADE;
+	gn->made = __BEINGMADE;
 	if (Make_OODate(gn)) {
@@ -1130,3 +1130,3 @@ MakeStartJobs(void)
 	    }
-	    gn->made = UPTODATE;
+	    gn->made = __UPTODATE;
 	    if (gn->type & OP_JOIN) {
@@ -1177,3 +1177,3 @@ MakePrintStatusOrder(void *ognp, void *gnp)

-    if (!(ogn->flags & REMAKE) || ogn->made > REQUESTED)
+    if (!(ogn->flags & REMAKE) || ogn->made > __REQUESTED)
 	/* not waiting for this one */
@@ -1206,11 +1206,11 @@ MakePrintStatus(void *gnp, void *v_errors)
 	switch (gn->made) {
-	case UPTODATE:
+	case __UPTODATE:
 	    printf("`%s%s' is up to date.\n", gn->name, gn->cohort_num);
 	    break;
-	case MADE:
+	case __MADE:
 	    break;
-	case UNMADE:
-	case DEFERRED:
-	case REQUESTED:
-	case BEINGMADE:
+	case __UNMADE:
+	case __DEFERRED:
+	case __REQUESTED:
+	case __BEINGMADE:
 	    (*errors)++;
diff --git a/make.h b/make.h
index c14b2c6..ea864b4 100644
--- a/make.h
+++ b/make.h
@@ -91,4 +91,10 @@
 #include <fcntl.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/fcntl.h"
+#endif
 #include <stdio.h>
 #include <stdlib.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/stdlib.h"
+#endif
 #ifdef HAVE_STRING_H
@@ -99,2 +105,5 @@
 #include <unistd.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/unistd.h"
+#endif
 #include <sys/cdefs.h>
@@ -203,4 +212,4 @@ typedef struct GNode {
     enum enum_made {
-	UNMADE, DEFERRED, REQUESTED, BEINGMADE,
-	MADE, UPTODATE, ERROR, ABORTED
+	__UNMADE, __DEFERRED, __REQUESTED, __BEINGMADE,
+        __MADE, __UPTODATE, __ERROR, __ABORTED
     }	    	    made;    	/* Set to reflect the state of processing
@@ -437,2 +446,3 @@ extern Lst	defIncPath;	/* The default include path. */
 extern char	curdir[];	/* Startup directory */
+extern char	*pcurdir;	/* Startup directory */
 extern char	*progname;	/* The program name */
@@ -466,3 +476,3 @@ extern pid_t	myPid;
  */
-FILE *debug_file;		/* Output written here - default stdout */
+extern FILE *debug_file;		/* Output written here - default stdout */
 extern int debug;
@@ -552,2 +562,12 @@ int cached_stat(const char *, void *);

+size_t str_escape(char *dst, const char *src, size_t dstLen);
+
+size_t str_escape_dblquote(char *dst, const char *src, size_t dstLen);
+
+char * str_replace_char(const char *s, const char toReplace, const char replacement);
+
+extern int system_np(const char* command, int timeout_milliseconds,
+              char* stdout_data, int stdout_data_size,
+              char* stderr_data, int stderr_data_size, int* exit_code);
+
 #endif /* _MAKE_H_ */
diff --git a/makefile.in b/makefile.in
deleted file mode 100644
index 03b980a..0000000
--- a/makefile.in
+++ /dev/null
@@ -1,14 +0,0 @@
-# $Id: makefile.in,v 1.1 2012/12/28 21:28:19 sjg Exp $
-
-# a simple makefile for those who don't like anything beyond:
-# ./configure; make; make install
-
-prefix= @prefix@
-srcdir= @srcdir@
-
-all: build
-
-build clean install test:
-	${srcdir}/boot-strap --prefix=${prefix} -o . op=$@
-
-
diff --git a/meta.c b/meta.c
index a852f3f..cd8c459 100644
--- a/meta.c
+++ b/meta.c
@@ -38,3 +38,10 @@
 #include <sys/stat.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_ioctl.h"
+#else
 #include <sys/ioctl.h>
+#endif
 #ifdef HAVE_LIBGEN_H
@@ -1613,4 +1620,6 @@ meta_compat_start(void)
     /* Set close-on-exec flag for both */
+#if defined(F_SETFD) && defined(FD_CLOEXEC)
     (void)fcntl(childPipe[0], F_SETFD, FD_CLOEXEC);
     (void)fcntl(childPipe[1], F_SETFD, FD_CLOEXEC);
+#endif
 }
diff --git a/mk/ChangeLog b/mk/ChangeLog
index ce8ac53..460ac78 100644
--- a/mk/ChangeLog
+++ b/mk/ChangeLog
@@ -946,4 +946,4 @@
 	    read-only manually maintained dependencies.
-	  o meta2deps.py add a clear 'ERROR:' token if an exception is raised.
-	  o gendirdeps.mk if ERROR: from meta2deps.py do not update
+	  o meta2deps.py add a clear '__ERROR:' token if an exception is raised.
+	  o gendirdeps.mk if __ERROR: from meta2deps.py do not update
 	    anything.
diff --git a/mk/gendirdeps.mk b/mk/gendirdeps.mk
index e04f839..5899574 100644
--- a/mk/gendirdeps.mk
+++ b/mk/gendirdeps.mk
@@ -196,4 +196,4 @@ dir_list != cd ${_OBJDIR} && \

-.if ${dir_list:M*ERROR\:*} != ""
-.warning ${dir_list:tW:C,.*(ERROR),\1,}
+.if ${dir_list:M*__ERROR\:*} != ""
+.warning ${dir_list:tW:C,.*(__ERROR),\1,}
 .warning Skipping ${_DEPENDFILE:S,${SRCTOP}/,,}
diff --git a/mk/host-target.mk b/mk/host-target.mk
index f528db9..1ab05b0 100644
--- a/mk/host-target.mk
+++ b/mk/host-target.mk
@@ -5,3 +5,3 @@
 .if !defined(_HOST_OSNAME)
-_HOST_OSNAME !=	uname -s
+_HOST_OSNAME !=	uname -s | cut -d_ -f1
 .export _HOST_OSNAME
diff --git a/mk/install-mk b/mk/install-mk
index 886c264..05f385d 100644
--- a/mk/install-mk
+++ b/mk/install-mk
@@ -115,3 +115,3 @@ Do() {
 Error() {
-	echo "ERROR: $@" >&2
+	echo "__ERROR: $@" >&2
 	exit 1
diff --git a/mk/meta.autodep.mk b/mk/meta.autodep.mk
index 9cb3f14..8c84502 100644
--- a/mk/meta.autodep.mk
+++ b/mk/meta.autodep.mk
@@ -316,3 +316,3 @@ _reldir_failed: .NOMETA
 .END: _reldir_finish
-.ERROR: _reldir_failed
+.__ERROR: _reldir_failed
 .endif
diff --git a/mk/meta.stage.mk b/mk/meta.stage.mk
index 320ffcc..d4f8a68 100644
--- a/mk/meta.stage.mk
+++ b/mk/meta.stage.mk
@@ -67,3 +67,3 @@ LN_CP_SCRIPT = LnCp() { \
 # a warning is handy when bootstapping different options.
-STAGE_CONFLICT?= ERROR
+STAGE_CONFLICT?= __ERROR
 .if ${STAGE_CONFLICT:tl} == "error"
diff --git a/mk/meta.sys.mk b/mk/meta.sys.mk
index 4dbdd79..de0e3b1 100644
--- a/mk/meta.sys.mk
+++ b/mk/meta.sys.mk
@@ -20,3 +20,3 @@
 .if ${MAKE_VERSION:U0} > 20100901
-.if !target(.ERROR)
+.if !target(.__ERROR)

@@ -94,3 +94,3 @@ meta_error_log = ${ERROR_LOGDIR}/meta-${.MAKE.PID}.log
 # we are not interested in make telling us a failure happened elsewhere
-.ERROR: _metaError
+.__ERROR: _metaError
 _metaError: .NOMETA .NOTMAIN
@@ -100,3 +100,3 @@ _metaError: .NOMETA .NOTMAIN
 	cp ${.ERROR_META_FILE} ${meta_error_log}; \
-	echo "ERROR: log ${meta_error_log}" >&2; }; :
+	echo "__ERROR: log ${meta_error_log}" >&2; }; :

@@ -139,3 +139,3 @@ UPDATE_DEPENDFILE= NO
 .elif !exists(/dev/filemon)
-.error ${.newline}ERROR: The filemon module (/dev/filemon) is not loaded.
+.error ${.newline}__ERROR: The filemon module (/dev/filemon) is not loaded.
 .endif
diff --git a/mk/own.mk b/mk/own.mk
index 4c8425b..37be01b 100644
--- a/mk/own.mk
+++ b/mk/own.mk
@@ -196,3 +196,3 @@ SHAREMODE?=	${NONBINMODE}
 COPY?=		-c
-STRIP_FLAG?=	-s
+STRIP_FLAG?=

diff --git a/mk/prog.mk b/mk/prog.mk
index 4bc6260..11bf182 100644
--- a/mk/prog.mk
+++ b/mk/prog.mk
@@ -26,3 +26,3 @@ CFLAGS+=	-mcmodel=medlow
 LIBCRTBEGIN=	${DESTDIR}/usr/lib/crtbegin.o
-.MADE: ${LIBCRTBEGIN}
+.__MADE: ${LIBCRTBEGIN}
 .endif
@@ -30,3 +30,3 @@ LIBCRTBEGIN=	${DESTDIR}/usr/lib/crtbegin.o
 LIBCRTEND=	${DESTDIR}/usr/lib/crtend.o
-.MADE: ${LIBCRTEND}
+.__MADE: ${LIBCRTEND}
 .endif
@@ -41,3 +41,3 @@ _SHLINKER=	${SHLINKDIR}/ld.so
 LIBCRT0=	${DESTDIR}/usr/lib/crt0.o
-.MADE: ${LIBCRT0}
+.__MADE: ${LIBCRT0}
 .endif
@@ -181,3 +181,3 @@ proginstall:
 	${INSTALL} ${COPY} ${STRIP_FLAG} ${PROG_INSTALL_OWN} -m ${BINMODE} \
-	    ${PROG} ${DESTDIR}${BINDIR}/${PROG_NAME}
+	    ${OBJTOP:tA}/${PROG} ${DESTDIR}${BINDIR}/${PROG_NAME}
 .endif
diff --git a/mk/sys/MINGW32.mk b/mk/sys/MINGW32.mk
new file mode 100644
index 0000000..10da919
--- /dev/null
+++ b/mk/sys/MINGW32.mk
@@ -0,0 +1,185 @@
+#	$Id: Linux.mk,v 1.9 2017/05/05 18:02:16 sjg Exp $
+#	$NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
+#	@(#)sys.mk	5.11 (Berkeley) 3/13/91
+
+OS?=		Windows
+unix?=		We run ${OS}.
+
+ROOT_GROUP=
+
+# would be better to work out where it is...
+LIBCRT0= /dev/null
+
+NEED_SOLINKS=yes
+
+.SUFFIXES: .out .a .ln .o .c ${CXX_SUFFIXES} .F .f .r .y .l .s .S .cl .p .h .sh .m4
+
+.LIBS:		.a
+
+AR=		ar
+ARFLAGS=	rl
+RANLIB=		ranlib
+
+AS=		as
+AFLAGS=
+COMPILE.s=	${AS} ${AFLAGS}
+LINK.s=		${CC} ${AFLAGS} ${LDFLAGS}
+COMPILE.S=	${CC} ${AFLAGS} ${CPPFLAGS} -c
+LINK.S=		${CC} ${AFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CC=		gcc -pipe
+DBG=		-O -g
+STATIC?=		-static
+
+CFLAGS=		${DBG}
+COMPILE.c=	${CC} ${CFLAGS} ${CPPFLAGS} -c
+LINK.c=		${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CXX=		g++
+CXXFLAGS=	${CFLAGS}
+COMPILE.cc=	${CXX} ${CXXFLAGS} ${CPPFLAGS} -c
+LINK.cc=	${CXX} ${CXXFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CPP=		cpp
+.if defined(DESTDIR)
+CPPFLAGS+=	-nostdinc -idirafter ${DESTDIR}/usr/include
+.endif
+
+MK_DEP=	mkdeps.sh -N
+FC=		f77
+FFLAGS=		-O
+RFLAGS=
+COMPILE.f=	${FC} ${FFLAGS} -c
+LINK.f=		${FC} ${FFLAGS} ${LDFLAGS}
+COMPILE.F=	${FC} ${FFLAGS} ${CPPFLAGS} -c
+LINK.F=		${FC} ${FFLAGS} ${CPPFLAGS} ${LDFLAGS}
+COMPILE.r=	${FC} ${FFLAGS} ${RFLAGS} -c
+LINK.r=		${FC} ${FFLAGS} ${RFLAGS} ${LDFLAGS}
+
+LEX=		lex
+LFLAGS=
+LEX.l=		${LEX} ${LFLAGS}
+
+LD=		ld
+LDFLAGS=
+
+LINT=		lint
+LINTFLAGS=	-chapbx
+
+PC=		pc
+PFLAGS=
+COMPILE.p=	${PC} ${PFLAGS} ${CPPFLAGS} -c
+LINK.p=		${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+SHELL=		sh
+
+YACC=		yacc
+YFLAGS=		-d
+YACC.y=		${YACC} ${YFLAGS}
+
+# C
+.c:
+	${LINK.c} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.c.o:
+	${COMPILE.c} ${.IMPSRC}
+.c.a:
+	${COMPILE.c} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# C++
+${CXX_SUFFIXES}:
+	${LINK.cc} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+${CXX_SUFFIXES:%=%.o}:
+	${COMPILE.cc} ${.IMPSRC}
+${CXX_SUFFIXES:%=%.a}:
+	${COMPILE.cc} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Fortran/Ratfor
+.f:
+	${LINK.f} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.f.o:
+	${COMPILE.f} ${.IMPSRC}
+.f.a:
+	${COMPILE.f} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+.F:
+	${LINK.F} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.F.o:
+	${COMPILE.F} ${.IMPSRC}
+.F.a:
+	${COMPILE.F} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+.r:
+	${LINK.r} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.r.o:
+	${COMPILE.r} ${.IMPSRC}
+.r.a:
+	${COMPILE.r} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Pascal
+.p:
+	${LINK.p} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.p.o:
+	${COMPILE.p} ${.IMPSRC}
+.p.a:
+	${COMPILE.p} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Assembly
+.s:
+	${LINK.s} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.s.o:
+	${COMPILE.s} -o ${.TARGET} ${.IMPSRC}
+.s.a:
+	${COMPILE.s} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+.S:
+	${LINK.S} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.S.o:
+	${COMPILE.S} ${.IMPSRC}
+.S.a:
+	${COMPILE.S} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Lex
+.l:
+	${LEX.l} ${.IMPSRC}
+	${LINK.c} -o ${.TARGET} lex.yy.c ${LDLIBS} -ll
+	rm -f lex.yy.c
+.l.c:
+	${LEX.l} ${.IMPSRC}
+	mv lex.yy.c ${.TARGET}
+.l.o:
+	${LEX.l} ${.IMPSRC}
+	${COMPILE.c} -o ${.TARGET} lex.yy.c
+	rm -f lex.yy.c
+
+# Yacc
+.y:
+	${YACC.y} ${.IMPSRC}
+	${LINK.c} -o ${.TARGET} y.tab.c ${LDLIBS}
+	rm -f y.tab.c
+.y.c:
+	${YACC.y} ${.IMPSRC}
+	mv y.tab.c ${.TARGET}
+.y.o:
+	${YACC.y} ${.IMPSRC}
+	${COMPILE.c} -o ${.TARGET} y.tab.c
+	rm -f y.tab.c
+
+# Shell
+.sh:
+	rm -f ${.TARGET}
+	cp ${.IMPSRC} ${.TARGET}
diff --git a/mk/sys/MINGW64.mk b/mk/sys/MINGW64.mk
new file mode 100644
index 0000000..10da919
--- /dev/null
+++ b/mk/sys/MINGW64.mk
@@ -0,0 +1,185 @@
+#	$Id: Linux.mk,v 1.9 2017/05/05 18:02:16 sjg Exp $
+#	$NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
+#	@(#)sys.mk	5.11 (Berkeley) 3/13/91
+
+OS?=		Windows
+unix?=		We run ${OS}.
+
+ROOT_GROUP=
+
+# would be better to work out where it is...
+LIBCRT0= /dev/null
+
+NEED_SOLINKS=yes
+
+.SUFFIXES: .out .a .ln .o .c ${CXX_SUFFIXES} .F .f .r .y .l .s .S .cl .p .h .sh .m4
+
+.LIBS:		.a
+
+AR=		ar
+ARFLAGS=	rl
+RANLIB=		ranlib
+
+AS=		as
+AFLAGS=
+COMPILE.s=	${AS} ${AFLAGS}
+LINK.s=		${CC} ${AFLAGS} ${LDFLAGS}
+COMPILE.S=	${CC} ${AFLAGS} ${CPPFLAGS} -c
+LINK.S=		${CC} ${AFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CC=		gcc -pipe
+DBG=		-O -g
+STATIC?=		-static
+
+CFLAGS=		${DBG}
+COMPILE.c=	${CC} ${CFLAGS} ${CPPFLAGS} -c
+LINK.c=		${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CXX=		g++
+CXXFLAGS=	${CFLAGS}
+COMPILE.cc=	${CXX} ${CXXFLAGS} ${CPPFLAGS} -c
+LINK.cc=	${CXX} ${CXXFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CPP=		cpp
+.if defined(DESTDIR)
+CPPFLAGS+=	-nostdinc -idirafter ${DESTDIR}/usr/include
+.endif
+
+MK_DEP=	mkdeps.sh -N
+FC=		f77
+FFLAGS=		-O
+RFLAGS=
+COMPILE.f=	${FC} ${FFLAGS} -c
+LINK.f=		${FC} ${FFLAGS} ${LDFLAGS}
+COMPILE.F=	${FC} ${FFLAGS} ${CPPFLAGS} -c
+LINK.F=		${FC} ${FFLAGS} ${CPPFLAGS} ${LDFLAGS}
+COMPILE.r=	${FC} ${FFLAGS} ${RFLAGS} -c
+LINK.r=		${FC} ${FFLAGS} ${RFLAGS} ${LDFLAGS}
+
+LEX=		lex
+LFLAGS=
+LEX.l=		${LEX} ${LFLAGS}
+
+LD=		ld
+LDFLAGS=
+
+LINT=		lint
+LINTFLAGS=	-chapbx
+
+PC=		pc
+PFLAGS=
+COMPILE.p=	${PC} ${PFLAGS} ${CPPFLAGS} -c
+LINK.p=		${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+SHELL=		sh
+
+YACC=		yacc
+YFLAGS=		-d
+YACC.y=		${YACC} ${YFLAGS}
+
+# C
+.c:
+	${LINK.c} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.c.o:
+	${COMPILE.c} ${.IMPSRC}
+.c.a:
+	${COMPILE.c} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# C++
+${CXX_SUFFIXES}:
+	${LINK.cc} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+${CXX_SUFFIXES:%=%.o}:
+	${COMPILE.cc} ${.IMPSRC}
+${CXX_SUFFIXES:%=%.a}:
+	${COMPILE.cc} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Fortran/Ratfor
+.f:
+	${LINK.f} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.f.o:
+	${COMPILE.f} ${.IMPSRC}
+.f.a:
+	${COMPILE.f} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+.F:
+	${LINK.F} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.F.o:
+	${COMPILE.F} ${.IMPSRC}
+.F.a:
+	${COMPILE.F} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+.r:
+	${LINK.r} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.r.o:
+	${COMPILE.r} ${.IMPSRC}
+.r.a:
+	${COMPILE.r} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Pascal
+.p:
+	${LINK.p} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.p.o:
+	${COMPILE.p} ${.IMPSRC}
+.p.a:
+	${COMPILE.p} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Assembly
+.s:
+	${LINK.s} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.s.o:
+	${COMPILE.s} -o ${.TARGET} ${.IMPSRC}
+.s.a:
+	${COMPILE.s} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+.S:
+	${LINK.S} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.S.o:
+	${COMPILE.S} ${.IMPSRC}
+.S.a:
+	${COMPILE.S} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Lex
+.l:
+	${LEX.l} ${.IMPSRC}
+	${LINK.c} -o ${.TARGET} lex.yy.c ${LDLIBS} -ll
+	rm -f lex.yy.c
+.l.c:
+	${LEX.l} ${.IMPSRC}
+	mv lex.yy.c ${.TARGET}
+.l.o:
+	${LEX.l} ${.IMPSRC}
+	${COMPILE.c} -o ${.TARGET} lex.yy.c
+	rm -f lex.yy.c
+
+# Yacc
+.y:
+	${YACC.y} ${.IMPSRC}
+	${LINK.c} -o ${.TARGET} y.tab.c ${LDLIBS}
+	rm -f y.tab.c
+.y.c:
+	${YACC.y} ${.IMPSRC}
+	mv y.tab.c ${.TARGET}
+.y.o:
+	${YACC.y} ${.IMPSRC}
+	${COMPILE.c} -o ${.TARGET} y.tab.c
+	rm -f y.tab.c
+
+# Shell
+.sh:
+	rm -f ${.TARGET}
+	cp ${.IMPSRC} ${.TARGET}
diff --git a/mk/sys/MSYS.mk b/mk/sys/MSYS.mk
new file mode 100644
index 0000000..10da919
--- /dev/null
+++ b/mk/sys/MSYS.mk
@@ -0,0 +1,185 @@
+#	$Id: Linux.mk,v 1.9 2017/05/05 18:02:16 sjg Exp $
+#	$NetBSD: sys.mk,v 1.19.2.1 1994/07/26 19:58:31 cgd Exp $
+#	@(#)sys.mk	5.11 (Berkeley) 3/13/91
+
+OS?=		Windows
+unix?=		We run ${OS}.
+
+ROOT_GROUP=
+
+# would be better to work out where it is...
+LIBCRT0= /dev/null
+
+NEED_SOLINKS=yes
+
+.SUFFIXES: .out .a .ln .o .c ${CXX_SUFFIXES} .F .f .r .y .l .s .S .cl .p .h .sh .m4
+
+.LIBS:		.a
+
+AR=		ar
+ARFLAGS=	rl
+RANLIB=		ranlib
+
+AS=		as
+AFLAGS=
+COMPILE.s=	${AS} ${AFLAGS}
+LINK.s=		${CC} ${AFLAGS} ${LDFLAGS}
+COMPILE.S=	${CC} ${AFLAGS} ${CPPFLAGS} -c
+LINK.S=		${CC} ${AFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CC=		gcc -pipe
+DBG=		-O -g
+STATIC?=		-static
+
+CFLAGS=		${DBG}
+COMPILE.c=	${CC} ${CFLAGS} ${CPPFLAGS} -c
+LINK.c=		${CC} ${CFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CXX=		g++
+CXXFLAGS=	${CFLAGS}
+COMPILE.cc=	${CXX} ${CXXFLAGS} ${CPPFLAGS} -c
+LINK.cc=	${CXX} ${CXXFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+CPP=		cpp
+.if defined(DESTDIR)
+CPPFLAGS+=	-nostdinc -idirafter ${DESTDIR}/usr/include
+.endif
+
+MK_DEP=	mkdeps.sh -N
+FC=		f77
+FFLAGS=		-O
+RFLAGS=
+COMPILE.f=	${FC} ${FFLAGS} -c
+LINK.f=		${FC} ${FFLAGS} ${LDFLAGS}
+COMPILE.F=	${FC} ${FFLAGS} ${CPPFLAGS} -c
+LINK.F=		${FC} ${FFLAGS} ${CPPFLAGS} ${LDFLAGS}
+COMPILE.r=	${FC} ${FFLAGS} ${RFLAGS} -c
+LINK.r=		${FC} ${FFLAGS} ${RFLAGS} ${LDFLAGS}
+
+LEX=		lex
+LFLAGS=
+LEX.l=		${LEX} ${LFLAGS}
+
+LD=		ld
+LDFLAGS=
+
+LINT=		lint
+LINTFLAGS=	-chapbx
+
+PC=		pc
+PFLAGS=
+COMPILE.p=	${PC} ${PFLAGS} ${CPPFLAGS} -c
+LINK.p=		${PC} ${PFLAGS} ${CPPFLAGS} ${LDFLAGS}
+
+SHELL=		sh
+
+YACC=		yacc
+YFLAGS=		-d
+YACC.y=		${YACC} ${YFLAGS}
+
+# C
+.c:
+	${LINK.c} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.c.o:
+	${COMPILE.c} ${.IMPSRC}
+.c.a:
+	${COMPILE.c} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# C++
+${CXX_SUFFIXES}:
+	${LINK.cc} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+${CXX_SUFFIXES:%=%.o}:
+	${COMPILE.cc} ${.IMPSRC}
+${CXX_SUFFIXES:%=%.a}:
+	${COMPILE.cc} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Fortran/Ratfor
+.f:
+	${LINK.f} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.f.o:
+	${COMPILE.f} ${.IMPSRC}
+.f.a:
+	${COMPILE.f} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+.F:
+	${LINK.F} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.F.o:
+	${COMPILE.F} ${.IMPSRC}
+.F.a:
+	${COMPILE.F} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+.r:
+	${LINK.r} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.r.o:
+	${COMPILE.r} ${.IMPSRC}
+.r.a:
+	${COMPILE.r} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Pascal
+.p:
+	${LINK.p} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.p.o:
+	${COMPILE.p} ${.IMPSRC}
+.p.a:
+	${COMPILE.p} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Assembly
+.s:
+	${LINK.s} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.s.o:
+	${COMPILE.s} -o ${.TARGET} ${.IMPSRC}
+.s.a:
+	${COMPILE.s} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+.S:
+	${LINK.S} -o ${.TARGET} ${.IMPSRC} ${LDLIBS}
+.S.o:
+	${COMPILE.S} ${.IMPSRC}
+.S.a:
+	${COMPILE.S} ${.IMPSRC}
+	${AR} ${ARFLAGS} $@ $*.o
+	rm -f $*.o
+
+# Lex
+.l:
+	${LEX.l} ${.IMPSRC}
+	${LINK.c} -o ${.TARGET} lex.yy.c ${LDLIBS} -ll
+	rm -f lex.yy.c
+.l.c:
+	${LEX.l} ${.IMPSRC}
+	mv lex.yy.c ${.TARGET}
+.l.o:
+	${LEX.l} ${.IMPSRC}
+	${COMPILE.c} -o ${.TARGET} lex.yy.c
+	rm -f lex.yy.c
+
+# Yacc
+.y:
+	${YACC.y} ${.IMPSRC}
+	${LINK.c} -o ${.TARGET} y.tab.c ${LDLIBS}
+	rm -f y.tab.c
+.y.c:
+	${YACC.y} ${.IMPSRC}
+	mv y.tab.c ${.TARGET}
+.y.o:
+	${YACC.y} ${.IMPSRC}
+	${COMPILE.c} -o ${.TARGET} y.tab.c
+	rm -f y.tab.c
+
+# Shell
+.sh:
+	rm -f ${.TARGET}
+	cp ${.IMPSRC} ${.TARGET}
diff --git a/mk/warnings.mk b/mk/warnings.mk
index 7fb3ebd..de664fd 100644
--- a/mk/warnings.mk
+++ b/mk/warnings.mk
@@ -69,4 +69,4 @@ _empty_warnings: .PHONY
 .endif
-	@echo "ERROR: Invalid: WARNINGS_SET=${ws}"
-	@echo "ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1
+	@echo "__ERROR: Invalid: WARNINGS_SET=${ws}"
+	@echo "__ERROR: Try one of: ${ALL_WARNINGS_SETS:O:u}"; exit 1

diff --git a/parse.c b/parse.c
index a7d7a4d..a996c49 100644
--- a/parse.c
+++ b/parse.c
@@ -127,2 +127,5 @@ __RCSID("$NetBSD: parse.c,v 1.231 2018/12/22 00:36:32 sjg Exp $");
 #include <sys/stat.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
 #include <assert.h>
@@ -2397,3 +2400,3 @@ ParseSetParseFile(const char *filename)
 {
-    char *slash, *dirname;
+    char *slash, *dirname, *pdirname;
     const char *pd, *pf;
@@ -2403,3 +2406,3 @@ ParseSetParseFile(const char *filename)
     if (slash == NULL) {
-	Var_Set(".PARSEDIR", pd = curdir, VAR_GLOBAL, 0);
+	Var_Set(".PARSEDIR", pd = pcurdir, VAR_GLOBAL, 0);
 	Var_Set(".PARSEFILE", pf = filename, VAR_GLOBAL, 0);
@@ -2411,3 +2414,19 @@ ParseSetParseFile(const char *filename)
 	dirname[len] = '\0';
-	Var_Set(".PARSEDIR", pd = dirname, VAR_GLOBAL, 0);
+#if (defined _WIN32 && ! defined __CYGWIN__)
+//        pdirname = str_replace_char(dirname, '\\', '/');
+//            if (pdirname[1] == ':') { // create msys-style windows path
+//                pdirname[1] = pdirname[0];
+//                pdirname[0] = '/';
+//            }
+    char *error;
+    if (dirname && strlen(dirname) > 0 && dirname[1] == ':'  && (dirname[2] == '/' || dirname[2] == '\\')) {
+        pdirname = Cmd_Exec(getUnixPathCmd(dirname), &error);
+    }
+    else {
+        pdirname = dirname;
+    }
+#else
+        pdirname = dirname;
+#endif
+	Var_Set(".PARSEDIR", pd = pdirname, VAR_GLOBAL, 0);
 	Var_Set(".PARSEFILE", pf = slash + 1, VAR_GLOBAL, 0);
diff --git a/pathnames.h b/pathnames.h
index 9c597b1..e3436a4 100644
--- a/pathnames.h
+++ b/pathnames.h
@@ -60,3 +60,7 @@
 #ifndef _PATH_TMP
-#define	_PATH_TMP		"/tmp/"		/* with trailing slash */
+# if (defined _WIN32 && ! defined __CYGWIN__)
+# define	_PATH_TMP		(getenv("TEMP"))
+# else
+# define	_PATH_TMP		"/tmp/"		/* with trailing slash */
+# endif
 #endif
diff --git a/realpath.c b/realpath.c
index fbf0335..9a6ac51 100644
--- a/realpath.c
+++ b/realpath.c
@@ -42,3 +42,5 @@
 #include <sys/stat.h>
-
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
 #include <errno.h>
@@ -51,3 +53,6 @@
 #ifdef HAVE_UNISTD_H
-# include <unistd.h>
+#include <unistd.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/unistd.h"
+#endif
 #endif
diff --git a/sigcompat.c b/sigcompat.c
index 608538d..9e605e9 100644
--- a/sigcompat.c
+++ b/sigcompat.c
@@ -91,4 +91,13 @@
 #include <signal.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/signal.h"
+#endif
+#ifndef SIGQUIT
+#define SIGQUIT SIGTERM
+#endif
 #ifdef HAVE_UNISTD_H
 #include <unistd.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/unistd.h"
+#endif
 #endif
diff --git a/str.c b/str.c
index b5255bc..cf85b95 100644
--- a/str.c
+++ b/str.c
@@ -526 +526,30 @@ Str_SYSVSubst(Buffer *buf, char *pat, char *src, int len)
 }
+
+char * str_replace_char(const char *s, const char toReplace, const char replacement)
+{
+    int len;
+    int count = 0;
+    char *result;
+
+
+
+    len = strlen(s);
+
+    /* allocate length plus EOS */
+    result = bmake_malloc((unsigned int)(len + 1));
+
+    /* copy first string into place */
+    memcpy(result, s, len + 1);
+
+    count = 0;
+    while(result[count]!='\0' && count < len)
+    {
+        if(result[count]==toReplace)
+        {
+            result[count]=replacement;
+        }
+        count++;
+    }
+
+    return result;
+}
diff --git a/targ.c b/targ.c
index 01c3d1c..17b14aa 100644
--- a/targ.c
+++ b/targ.c
@@ -248,3 +248,3 @@ Targ_NewGN(const char *name)
     gn->centurion =    	NULL;
-    gn->made = 	    	UNMADE;
+    gn->made = 	    	__UNMADE;
     gn->flags = 	0;
@@ -605,10 +605,10 @@ made_name(enum enum_made made)
     switch (made) {
-    case UNMADE:     return "unmade";
-    case DEFERRED:   return "deferred";
-    case REQUESTED:  return "requested";
-    case BEINGMADE:  return "being made";
-    case MADE:       return "made";
-    case UPTODATE:   return "up-to-date";
-    case ERROR:      return "error when made";
-    case ABORTED:    return "aborted";
+    case __UNMADE:     return "unmade";
+    case __DEFERRED:   return "deferred";
+    case __REQUESTED:  return "requested";
+    case __BEINGMADE:  return "being made";
+    case __MADE:       return "made";
+    case __UPTODATE:   return "up-to-date";
+    case __ERROR:      return "error when made";
+    case __ABORTED:    return "aborted";
     default:         return "unknown enum_made value";
@@ -650,3 +650,3 @@ Targ_PrintNode(void *gnp, void *passp)
 			      made_name(gn->made));
-		} else if (gn->made != UNMADE) {
+		} else if (gn->made != __UNMADE) {
 		    fprintf(debug_file, "# non-existent (maybe): %s\n",
diff --git a/trace.c b/trace.c
index 267177f..f0f8693 100644
--- a/trace.c
+++ b/trace.c
@@ -58,2 +58,5 @@ __RCSID("$NetBSD: trace.c,v 1.11 2008/12/28 18:31:51 christos Exp $");
 #include <unistd.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/unistd.h"
+#endif

diff --git a/unit-tests/Makefile b/unit-tests/Makefile
new file mode 100644
index 0000000..bd45de7
--- /dev/null
+++ b/unit-tests/Makefile
@@ -0,0 +1,152 @@
+# $Id: Makefile.in,v 1.49 2018/09/21 21:39:05 sjg Exp $
+#
+# $NetBSD: Makefile,v 1.53 2018/05/24 00:25:44 christos Exp $
+#
+# Unit tests for make(1)
+# The main targets are:
+#
+# all:	run all the tests
+# test:	run 'all', and compare to expected results
+# accept: move generated output to expected results
+#
+# Adding a test case.
+# Each feature should get its own set of tests in its own suitably
+# named makefile (*.mk), with its own set of expected results (*.exp),
+# and it should be added to the TESTNAMES list.
+#
+
+srcdir= /home/ofry/bmake/unit-tests
+
+.MAIN: all
+
+UNIT_TESTS:= ${srcdir}
+WIN_UNIT_TESTS != cygpath -m ${srcdir}
+.PATH: ${UNIT_TESTS}
+
+# Each test is in a sub-makefile.
+# Keep the list sorted.
+TESTNAMES= \
+	comment \
+	cond1 \
+	cond2 \
+	error \
+	export \
+	export-all \
+	export-env \
+	doterror \
+	forloop \
+	forsubst \
+	hash \
+	misc \
+	moderrs \
+	modmatch \
+	modmisc \
+	modorder \
+	modts \
+	modword \
+	qequals \
+	sunshcmd \
+	sysv \
+	ternary \
+	unexport \
+	unexport-env \
+	varcmd \
+	varmisc \
+	varquote \
+	varshell
+
+# these tests were broken by referting POSIX chanegs
+STRICT_POSIX_TESTS = \
+	escape \
+	impsrc \
+	phony-end \
+	posix1 \
+	suffixes
+
+# Override make flags for certain tests
+flags.doterror=
+flags.order=-j1
+
+OUTFILES= ${TESTNAMES:S/$/.out/}
+
+all: ${OUTFILES}
+
+CLEANFILES += *.rawout *.out *.status *.tmp *.core *.tmp
+CLEANFILES += obj*.[och] lib*.a		# posix1.mk
+CLEANFILES += issue* .[ab]*		# suffixes.mk
+CLEANRECURSIVE += dir dummy		# posix1.mk
+
+clean:
+	rm -f ${CLEANFILES}
+.if !empty(CLEANRECURSIVE)
+	rm -rf ${CLEANRECURSIVE}
+.endif
+
+TEST_MAKE?= ${.MAKE}
+TOOL_SED?= sed
+TOOL_TR?= tr
+TOOL_DIFF?= diff
+DIFF_FLAGS?= -u
+
+.if defined(.PARSEDIR)
+# ensure consistent results from sort(1)
+LC_ALL= C
+LANG= C
+.export LANG LC_ALL
+.endif
+
+# some tests need extra post-processing
+SED_CMDS.varshell = -e 's,^[a-z]*sh: ,,' \
+	-e '/command/s,No such.*,not found,'
+
+# the tests are actually done with sub-makes.
+.SUFFIXES: .mk .rawout .out
+.mk.rawout:
+	@echo ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC}
+	-@cd ${.OBJDIR} && \
+	{ ${TEST_MAKE} ${flags.${.TARGET:R}:U-k} -f ${.IMPSRC} \
+	  2>&1 ; echo $$? >${.TARGET:R}.status ; } > ${.TARGET}.tmp
+	@mv ${.TARGET}.tmp ${.TARGET}
+
+# We always pretend .MAKE was called 'make'
+# and strip ${.CURDIR}/ from the output
+# and replace anything after 'stopped in' with unit-tests
+# so the results can be compared.
+.rawout.out:
+	@echo postprocess ${.TARGET}
+	@${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}[][0-9]*:,make:,' \
+	  -e 's,^${TEST_MAKE:T:C/\./\\\./g}\.exe[][0-9]*:,make:,' \
+	  -e 's,${TEST_MAKE:C/\./\\\./g},make,' \
+	  -e '/stopped/s, /.*, unit-tests,' \
+	  -e 's,${.CURDIR:C/\./\\\./g}/,,g' \
+	  -e 's,${WIN_UNIT_TESTS:C/\./\\\./g},unit-tests,g' \
+	  -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' ${SED_CMDS.${.TARGET:T:R}} \
+	  < ${.IMPSRC} > ${.TARGET}.tmp
+	@echo "exit status `cat ${.TARGET:R}.status`" >> ${.TARGET}.tmp
+	@mv ${.TARGET}.tmp ${.TARGET}
+
+# Compare all output files
+test:	${OUTFILES} .PHONY
+	@failed= ; \
+	for test in ${TESTNAMES}; do \
+	  ${TOOL_DIFF} ${DIFF_FLAGS} ${UNIT_TESTS}/$${test}.exp $${test}.out \
+	  || failed="$${failed}$${failed:+ }$${test}" ; \
+	done ; \
+	if [ -n "$${failed}" ]; then \
+	  echo "Failed tests: $${failed}" ; false ; \
+	else \
+	  echo "All tests passed" ; \
+	fi
+
+accept:
+	@for test in ${TESTNAMES}; do \
+	  cmp -s ${UNIT_TESTS}/$${test}.exp $${test}.out \
+	  || { echo "Replacing $${test}.exp" ; \
+	       cp $${test}.out ${UNIT_TESTS}/$${test}.exp ; } \
+	done
+
+.if exists(${TEST_MAKE})
+${TESTNAMES:S/$/.rawout/}: ${TEST_MAKE}
+.endif
+
+.-include <obj.mk>
diff --git a/unit-tests/Makefile.in b/unit-tests/Makefile.in
index e51d254..c24bc33 100644
--- a/unit-tests/Makefile.in
+++ b/unit-tests/Makefile.in
@@ -22,2 +22,3 @@ srcdir= @srcdir@
 UNIT_TESTS:= ${srcdir}
+WIN_UNIT_TESTS != cygpath -m ${srcdir}
 .PATH: ${UNIT_TESTS}
@@ -35,3 +36,2 @@ TESTNAMES= \
 	doterror \
-	dotwait \
 	forloop \
@@ -46,4 +46,2 @@ TESTNAMES= \
 	modword \
-	order \
-	posix \
 	qequals \
@@ -119,2 +117,3 @@ SED_CMDS.varshell = -e 's,^[a-z]*sh: ,,' \
 	@${TOOL_SED} -e 's,^${TEST_MAKE:T:C/\./\\\./g}[][0-9]*:,make:,' \
+	  -e 's,^${TEST_MAKE:T:C/\./\\\./g}\.exe[][0-9]*:,make:,' \
 	  -e 's,${TEST_MAKE:C/\./\\\./g},make,' \
@@ -122,2 +121,3 @@ SED_CMDS.varshell = -e 's,^[a-z]*sh: ,,' \
 	  -e 's,${.CURDIR:C/\./\\\./g}/,,g' \
+	  -e 's,${WIN_UNIT_TESTS:C/\./\\\./g},unit-tests,g' \
 	  -e 's,${UNIT_TESTS:C/\./\\\./g}/,,g' ${SED_CMDS.${.TARGET:T:R}} \
diff --git a/unit-tests/doterror.exp b/unit-tests/doterror.exp
index 5655644..1c8b971 100644
--- a/unit-tests/doterror.exp
+++ b/unit-tests/doterror.exp
@@ -7,3 +7,3 @@ Stop.
 make: stopped in unit-tests
-.ERROR: Looks like 'sad' is upset.
+.__ERROR: Looks like 'sad' is upset.
 exit status 1
diff --git a/unit-tests/doterror.mk b/unit-tests/doterror.mk
index 9030dce..676e2e6 100644
--- a/unit-tests/doterror.mk
+++ b/unit-tests/doterror.mk
@@ -9,3 +9,3 @@

-.ERROR:
+.__ERROR:
 	@echo "$@: Looks like '${.ERROR_TARGET}' is upset."
diff --git a/unit-tests/escape.mk b/unit-tests/escape.mk
index bb37c92..3bf1b1f 100644
--- a/unit-tests/escape.mk
+++ b/unit-tests/escape.mk
@@ -53,3 +53,3 @@ should continue the comment. \

-__printvars: .USE .MADE
+__printvars: .USE .__MADE
 	@echo ${.TARGET}
diff --git a/util.c b/util.c
index c79f645..25f4f5e 100644
--- a/util.c
+++ b/util.c
@@ -9,2 +9,8 @@
 #include <signal.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/signal.h"
+#endif
+#ifndef SIGQUIT
+#define SIGQUIT SIGTERM
+#endif
 #endif
@@ -24,17 +30,487 @@ __RCSID("$NetBSD: util.c,v 1.54 2013/11/26 13:44:41 joerg Exp $");
 #include <signal.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/signal.h"
+#endif
+#ifndef SIGQUIT
+#define SIGQUIT SIGTERM
+#endif

-#if !defined(HAVE_STRERROR)
-extern int errno, sys_nerr;
-extern char *sys_errlist[];
+#ifndef NO_REGEX

-char *
-strerror(int e)
+#include    <sys/types.h>
+
+# if (defined _WIN32 && !defined __CYGWIN__)
+#include "headers-mingw/regex.h"
+#include "headers-mingw/regex_internal.h"
+# else
+
+#include    <regex.h>
+
+# endif
+#endif
+
+#if !defined(HAVE_PIPE) && (defined _WIN32 && ! defined __CYGWIN__)
+/* Create a pipe.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+/* Specification.  */
+#include <unistd.h>
+#include "headers-mingw/unistd.h"
+/* Native Windows API.  */
+
+/* Get _pipe().  */
+#include <io.h>
+
+/* Get _O_BINARY.  */
+#include <fcntl.h>
+#include "headers-mingw/fcntl.h"
+
+int
+pipe (int fd[2])
 {
-    static char buf[100];
-    if (e < 0 || e >= sys_nerr) {
-	snprintf(buf, sizeof(buf), "Unknown error %d", e);
-	return buf;
+  /* Mingw changes fd to {-1,-1} on failure, but this violates
+     http://austingroupbugs.net/view.php?id=467 */
+  int tmp[2];
+  int result = _pipe (tmp, 4096, _O_BINARY);
+  if (!result)
+    {
+      fd[0] = tmp[0];
+      fd[1] = tmp[1];
     }
-    else
-	return sys_errlist[e];
+  return result;
+}
+
+#endif
+
+#if !defined(HAVE_GETDTABLESIZE) && (defined _WIN32 && ! defined __CYGWIN__)
+/* getdtablesize() function: Return maximum possible file descriptor value + 1.
+   Copyright (C) 2008-2018 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2008.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Specification.  */
+#include <unistd.h>
+#include "headers-mingw/unistd.h"
+
+# include <stdio.h>
+
+#  define _setmaxstdio_nothrow _setmaxstdio
+
+/* Cache for the previous getdtablesize () result.  Safe to cache because
+   Windows also lacks setrlimit.  */
+static int dtablesize;
+
+int
+getdtablesize (void)
+{
+  if (dtablesize == 0)
+    {
+      /* We are looking for the number N such that the valid file descriptors
+         are 0..N-1.  It can be obtained through a loop as follows:
+           {
+             int fd;
+             for (fd = 3; fd < 65536; fd++)
+               if (dup2 (0, fd) == -1)
+                 break;
+             return fd;
+           }
+         On Windows XP, the result is 2048.
+         The drawback of this loop is that it allocates memory for a libc
+         internal array that is never freed.
+
+         The number N can also be obtained as the upper bound for
+         _getmaxstdio ().  _getmaxstdio () returns the maximum number of open
+         FILE objects.  The sanity check in _setmaxstdio reveals the maximum
+         number of file descriptors.  This too allocates memory, but it is
+         freed when we call _setmaxstdio with the original value.  */
+      int orig_max_stdio = _getmaxstdio ();
+      unsigned int bound;
+      for (bound = 0x10000; _setmaxstdio_nothrow (bound) < 0; bound = bound / 2)
+        ;
+      _setmaxstdio_nothrow (orig_max_stdio);
+      dtablesize = bound;
+    }
+  return dtablesize;
+}
+
+#endif
+
+#if !defined(HAVE_FCNTL) && (defined _WIN32 && ! defined __CYGWIN__)
+/* Provide file descriptor control.
+
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Written by Eric Blake <ebb9@byu.net>.  */
+
+/* Specification.  */
+#include "headers-mingw/fcntl.h"
+
+#include <errno.h>
+#include <limits.h>
+#include <stdarg.h>
+#include <unistd.h>
+
+/* Get declarations of the native Windows API functions.  */
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+/* Get _get_osfhandle.  */
+# if GNULIB_MSVC_NOTHROW
+#  include "msvc-nothrow.h"
+# else
+#  include <io.h>
+# endif
+
+/* Upper bound on getdtablesize().  See lib/getdtablesize.c.  */
+# define OPEN_MAX_MAX 0x10000
+
+/* Duplicate OLDFD into the first available slot of at least NEWFD,
+   which must be positive, with FLAGS determining whether the duplicate
+   will be inheritable.  */
+static int
+dupfd (int oldfd, int newfd, int flags)
+{
+  /* Mingw has no way to create an arbitrary fd.  Iterate until all
+     file descriptors less than newfd are filled up.  */
+  HANDLE curr_process = GetCurrentProcess ();
+  HANDLE old_handle = (HANDLE) _get_osfhandle (oldfd);
+  unsigned char fds_to_close[OPEN_MAX_MAX / CHAR_BIT];
+  unsigned int fds_to_close_bound = 0;
+  int result;
+  BOOL inherit = flags & O_CLOEXEC ? FALSE : TRUE;
+  int mode;
+
+  if (newfd < 0 || getdtablesize () <= newfd)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  if (old_handle == INVALID_HANDLE_VALUE
+      || (mode = setmode (oldfd, O_BINARY)) == -1)
+    {
+      /* oldfd is not open, or is an unassigned standard file
+         descriptor.  */
+      errno = EBADF;
+      return -1;
+    }
+  setmode (oldfd, mode);
+  flags |= mode;
+
+  for (;;)
+    {
+      HANDLE new_handle;
+      int duplicated_fd;
+      unsigned int index;
+
+      if (!DuplicateHandle (curr_process,           /* SourceProcessHandle */
+                            old_handle,             /* SourceHandle */
+                            curr_process,           /* TargetProcessHandle */
+                            (PHANDLE) &new_handle,  /* TargetHandle */
+                            (DWORD) 0,              /* DesiredAccess */
+                            inherit,                /* InheritHandle */
+                            DUPLICATE_SAME_ACCESS)) /* Options */
+        {
+          switch (GetLastError ())
+            {
+              case ERROR_TOO_MANY_OPEN_FILES:
+                errno = EMFILE;
+                break;
+              case ERROR_INVALID_HANDLE:
+              case ERROR_INVALID_TARGET_HANDLE:
+              case ERROR_DIRECT_ACCESS_HANDLE:
+                errno = EBADF;
+                break;
+              case ERROR_INVALID_PARAMETER:
+              case ERROR_INVALID_FUNCTION:
+              case ERROR_INVALID_ACCESS:
+                errno = EINVAL;
+                break;
+              default:
+                errno = EACCES;
+                break;
+            }
+          result = -1;
+          break;
+        }
+      duplicated_fd = _open_osfhandle ((intptr_t) new_handle, flags);
+      if (duplicated_fd < 0)
+        {
+          CloseHandle (new_handle);
+          result = -1;
+          break;
+        }
+      if (newfd <= duplicated_fd)
+        {
+          result = duplicated_fd;
+          break;
+        }
+
+      /* Set the bit duplicated_fd in fds_to_close[].  */
+      index = (unsigned int) duplicated_fd / CHAR_BIT;
+      if (fds_to_close_bound <= index)
+        {
+          if (sizeof fds_to_close <= index)
+            /* Need to increase OPEN_MAX_MAX.  */
+            abort ();
+          memset (fds_to_close + fds_to_close_bound, '\0',
+                  index + 1 - fds_to_close_bound);
+          fds_to_close_bound = index + 1;
+        }
+      fds_to_close[index] |= 1 << ((unsigned int) duplicated_fd % CHAR_BIT);
+    }
+
+  /* Close the previous fds that turned out to be too small.  */
+  {
+    int saved_errno = errno;
+    unsigned int duplicated_fd;
+
+    for (duplicated_fd = 0;
+         duplicated_fd < fds_to_close_bound * CHAR_BIT;
+         duplicated_fd++)
+      if ((fds_to_close[duplicated_fd / CHAR_BIT]
+           >> (duplicated_fd % CHAR_BIT))
+          & 1)
+        close (duplicated_fd);
+
+    errno = saved_errno;
+  }
+  return result;
+}
+
+/* Forward declarations, because we '#undef fcntl' in the middle of this
+   compilation unit.  */
+/* Our implementation of fcntl (fd, F_DUPFD, target).  */
+static int rpl_fcntl_DUPFD (int fd, int target);
+/* Our implementation of fcntl (fd, F_DUPFD_CLOEXEC, target).  */
+static int rpl_fcntl_DUPFD_CLOEXEC (int fd, int target);
+
+/* Perform the specified ACTION on the file descriptor FD, possibly
+   using the argument ARG further described below.  This replacement
+   handles the following actions, and forwards all others on to the
+   native fcntl.  An unrecognized ACTION returns -1 with errno set to
+   EINVAL.
+
+   F_DUPFD - duplicate FD, with int ARG being the minimum target fd.
+   If successful, return the duplicate, which will be inheritable;
+   otherwise return -1 and set errno.
+
+   F_DUPFD_CLOEXEC - duplicate FD, with int ARG being the minimum
+   target fd.  If successful, return the duplicate, which will not be
+   inheritable; otherwise return -1 and set errno.
+
+   F_GETFD - ARG need not be present.  If successful, return a
+   non-negative value containing the descriptor flags of FD (only
+   FD_CLOEXEC is portable, but other flags may be present); otherwise
+   return -1 and set errno.  */
+
+int
+fcntl (int fd, int action, /* arg */...)
+{
+  va_list arg;
+  int result = -1;
+  va_start (arg, action);
+  switch (action)
+    {
+    case F_DUPFD:
+      {
+        int target = va_arg (arg, int);
+        result = rpl_fcntl_DUPFD (fd, target);
+        break;
+      }
+
+    case F_DUPFD_CLOEXEC:
+      {
+        int target = va_arg (arg, int);
+        result = rpl_fcntl_DUPFD_CLOEXEC (fd, target);
+        break;
+      }
+
+    case F_GETFD:
+      {
+        HANDLE handle = (HANDLE) _get_osfhandle (fd);
+        DWORD flags;
+        if (handle == INVALID_HANDLE_VALUE
+            || GetHandleInformation (handle, &flags) == 0)
+          errno = EBADF;
+        else
+          result = (flags & HANDLE_FLAG_INHERIT) ? 0 : FD_CLOEXEC;
+        break;
+      } /* F_GETFD */
+
+      /* Implementing F_SETFD on mingw is not trivial - there is no
+         API for changing the O_NOINHERIT bit on an fd, and merely
+         changing the HANDLE_FLAG_INHERIT bit on the underlying handle
+         can lead to odd state.  It may be possible by duplicating the
+         handle, using _open_osfhandle with the right flags, then
+         using dup2 to move the duplicate onto the original, but that
+         is not supported for now.  */
+
+    default:
+      {
+        errno = EINVAL;
+        break;
+      }
+    }
+  va_end (arg);
+  return result;
+}
+
+static int
+rpl_fcntl_DUPFD (int fd, int target)
+{
+  int result;
+  result = dupfd (fd, target, 0);
+  return result;
+}
+
+static int
+rpl_fcntl_DUPFD_CLOEXEC (int fd, int target)
+{
+  int result;
+  result = dupfd (fd, target, O_CLOEXEC);
+  return result;
+}
+
+#endif
+
+#if !defined(HAVE_FORK) && (defined _WIN32 && ! defined __CYGWIN__)
+/*
+ * fork.c
+ * Experimental fork() on Windows.  Requires NT 6 subsystem or
+ * newer.
+ *
+ * Copyright (c) 2012 William Pitcock <nenolod@dereferenced.org>
+ *
+ * Permission to use, copy, modify, and/or distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * This software is provided 'as is' and without any warranty, express or
+ * implied.  In no event shall the authors be liable for any damages arising
+ * from the use of this software.
+ */
+
+#define WIN32_LEAN_AND_MEAN
+#include <windows.h>
+#include <winnt.h>
+#include <winternl.h>
+#include <stdio.h>
+#include <errno.h>
+#include <process.h>
+
+typedef struct _SECTION_IMAGE_INFORMATION {
+	PVOID EntryPoint;
+	ULONG StackZeroBits;
+	ULONG StackReserved;
+	ULONG StackCommit;
+	ULONG ImageSubsystem;
+	WORD SubSystemVersionLow;
+	WORD SubSystemVersionHigh;
+	ULONG Unknown1;
+	ULONG ImageCharacteristics;
+	ULONG ImageMachineType;
+	ULONG Unknown2[3];
+} SECTION_IMAGE_INFORMATION, *PSECTION_IMAGE_INFORMATION;
+
+typedef struct _RTL_USER_PROCESS_INFORMATION {
+	ULONG Size;
+	HANDLE Process;
+	HANDLE Thread;
+	CLIENT_ID ClientId;
+	SECTION_IMAGE_INFORMATION ImageInformation;
+} RTL_USER_PROCESS_INFORMATION, *PRTL_USER_PROCESS_INFORMATION;
+
+#define RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED	0x00000001
+#define RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES		0x00000002
+#define RTL_CLONE_PROCESS_FLAGS_NO_SYNCHRONIZE		0x00000004
+
+#define RTL_CLONE_PARENT				0
+#define RTL_CLONE_CHILD					297
+
+typedef NTSTATUS (*RtlCloneUserProcess_f)(ULONG ProcessFlags,
+	PSECURITY_DESCRIPTOR ProcessSecurityDescriptor /* optional */,
+	PSECURITY_DESCRIPTOR ThreadSecurityDescriptor /* optional */,
+	HANDLE DebugPort /* optional */,
+	PRTL_USER_PROCESS_INFORMATION ProcessInformation);
+
+pid_t fork(void)
+{
+	HMODULE mod;
+	RtlCloneUserProcess_f clone_p;
+	RTL_USER_PROCESS_INFORMATION process_info;
+	NTSTATUS result;
+
+	mod = GetModuleHandle("ntdll.dll");
+	if (!mod)
+		return -ENOSYS;
+
+	clone_p = (RtlCloneUserProcess_f)GetProcAddress(mod, "RtlCloneUserProcess");
+	if (clone_p == NULL)
+		return -ENOSYS;
+
+	/* lets do this */
+	result = clone_p(RTL_CLONE_PROCESS_FLAGS_CREATE_SUSPENDED | RTL_CLONE_PROCESS_FLAGS_INHERIT_HANDLES, NULL, NULL, NULL, &process_info);
+
+	if (result == RTL_CLONE_PARENT)
+	{
+		HANDLE me, hp, ht, hcp = 0;
+		DWORD pi, ti, mi;
+		me = GetCurrentProcess();
+		pi = (DWORD)process_info.ClientId.UniqueProcess;
+		ti = (DWORD)process_info.ClientId.UniqueThread;
+
+		ResumeThread(ht);
+		CloseHandle(ht);
+		CloseHandle(hp);
+		return (pid_t)pi;
+	}
+	else if (result == RTL_CLONE_CHILD)
+	{
+		/* fix stdio */
+		AllocConsole();
+		return 0;
+	}
+	else
+		return -1;
+
+	/* NOTREACHED */
+	return -1;
 }
@@ -221,2 +697,5 @@ char    *sys_siglist[] = {
 #include <sys/stat.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
 #include <dirent.h>
@@ -224,2 +703,5 @@ char    *sys_siglist[] = {
 #include <unistd.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/unistd.h"
+#endif

@@ -367,2 +849,641 @@ getwd(char *pathname)

+#if !defined(HAVE_RANDOM)
+/* Copyright (C) 1995-2018 Free Software Foundation, Inc.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+/*
+ * This is derived from the Berkeley source:
+ *      @(#)random.c    5.5 (Berkeley) 7/6/88
+ * It was reworked for the GNU C Library by Roland McGrath.
+ * Rewritten to use reentrant functions by Ulrich Drepper, 1995.
+ */
+
+/*
+   Copyright (C) 1983 Regents of the University of California.
+   All rights reserved.
+
+   Redistribution and use in source and binary forms, with or without
+   modification, are permitted provided that the following conditions
+   are met:
+
+   1. Redistributions of source code must retain the above copyright
+      notice, this list of conditions and the following disclaimer.
+   2. Redistributions in binary form must reproduce the above copyright
+      notice, this list of conditions and the following disclaimer in the
+      documentation and/or other materials provided with the distribution.
+   4. Neither the name of the University nor the names of its contributors
+      may be used to endorse or promote products derived from this software
+      without specific prior written permission.
+
+   THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS "AS IS" AND
+   ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+   IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+   ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+   FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+   DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+   OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+   HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+   LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+   OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+   SUCH DAMAGE.*/
+
+#ifndef _LIBC
+# include "headers-mingw/libc-config.h"
+#endif
+
+/* Specification.  */
+#include <stdlib.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/stdlib.h"
+#endif
+
+#include <errno.h>
+#include <stddef.h>
+#include <string.h>
+
+#ifdef _LIBC
+# include <libc-lock.h>
+#else
+/* Allow memory races; that's random enough.  */
+# define __libc_lock_define_initialized(class, name)
+# define __libc_lock_lock(name) ((void) 0)
+# define __libc_lock_unlock(name) ((void) 0)
+#endif
+
+/* An improved random number generation package.  In addition to the standard
+   rand()/srand() like interface, this package also has a special state info
+   interface.  The initstate() routine is called with a seed, an array of
+   bytes, and a count of how many bytes are being passed in; this array is
+   then initialized to contain information for random number generation with
+   that much state information.  Good sizes for the amount of state
+   information are 32, 64, 128, and 256 bytes.  The state can be switched by
+   calling the setstate() function with the same array as was initialized
+   with initstate().  By default, the package runs with 128 bytes of state
+   information and generates far better random numbers than a linear
+   congruential generator.  If the amount of state information is less than
+   32 bytes, a simple linear congruential R.N.G. is used.  Internally, the
+   state information is treated as an array of longs; the zeroth element of
+   the array is the type of R.N.G. being used (small integer); the remainder
+   of the array is the state information for the R.N.G.  Thus, 32 bytes of
+   state information will give 7 longs worth of state information, which will
+   allow a degree seven polynomial.  (Note: The zeroth word of state
+   information also has some other information stored in it; see setstate
+   for details).  The random number generation technique is a linear feedback
+   shift register approach, employing trinomials (since there are fewer terms
+   to sum up that way).  In this approach, the least significant bit of all
+   the numbers in the state table will act as a linear feedback shift register,
+   and will have period 2^deg - 1 (where deg is the degree of the polynomial
+   being used, assuming that the polynomial is irreducible and primitive).
+   The higher order bits will have longer periods, since their values are
+   also influenced by pseudo-random carries out of the lower bits.  The
+   total period of the generator is approximately deg*(2**deg - 1); thus
+   doubling the amount of state information has a vast influence on the
+   period of the generator.  Note: The deg*(2**deg - 1) is an approximation
+   only good for large deg, when the period of the shift register is the
+   dominant factor.  With deg equal to seven, the period is actually much
+   longer than the 7*(2**7 - 1) predicted by this formula.  */
+
+
+
+/* For each of the currently supported random number generators, we have a
+   break value on the amount of state information (you need at least this many
+   bytes of state info to support this random number generator), a degree for
+   the polynomial (actually a trinomial) that the R.N.G. is based on, and
+   separation between the two lower order coefficients of the trinomial.  */
+
+/* Linear congruential.  */
+#define TYPE_0          0
+#define BREAK_0         8
+#define DEG_0           0
+#define SEP_0           0
+
+/* x**7 + x**3 + 1.  */
+#define TYPE_1          1
+#define BREAK_1         32
+#define DEG_1           7
+#define SEP_1           3
+
+/* x**15 + x + 1.  */
+#define TYPE_2          2
+#define BREAK_2         64
+#define DEG_2           15
+#define SEP_2           1
+
+/* x**31 + x**3 + 1.  */
+#define TYPE_3          3
+#define BREAK_3         128
+#define DEG_3           31
+#define SEP_3           3
+
+/* x**63 + x + 1.  */
+#define TYPE_4          4
+#define BREAK_4         256
+#define DEG_4           63
+#define SEP_4           1
+
+
+/* Array versions of the above information to make code run faster.
+   Relies on fact that TYPE_i == i.  */
+
+#define MAX_TYPES       5       /* Max number of types above.  */
+
+
+/* Initially, everything is set up as if from:
+        initstate(1, randtbl, 128);
+   Note that this initialization takes advantage of the fact that srandom
+   advances the front and rear pointers 10*rand_deg times, and hence the
+   rear pointer which starts at 0 will also end up at zero; thus the zeroth
+   element of the state information, which contains info about the current
+   position of the rear pointer is just
+        (MAX_TYPES * (rptr - state)) + TYPE_3 == TYPE_3.  */
+
+static int32_t randtbl[DEG_3 + 1] =
+        {
+                TYPE_3,
+
+                -1726662223, 379960547, 1735697613, 1040273694, 1313901226,
+                1627687941, -179304937, -2073333483, 1780058412, -1989503057,
+                -615974602, 344556628, 939512070, -1249116260, 1507946756,
+                -812545463, 154635395, 1388815473, -1926676823, 525320961,
+                -1009028674, 968117788, -123449607, 1284210865, 435012392,
+                -2017506339, -911064859, -370259173, 1132637927, 1398500161,
+                -205601318,
+        };
+
+
+static struct random_data unsafe_state =
+        {
+/* FPTR and RPTR are two pointers into the state info, a front and a rear
+   pointer.  These two pointers are always rand_sep places apart, as they
+   cycle through the state information.  (Yes, this does mean we could get
+   away with just one pointer, but the code for random is more efficient
+   this way).  The pointers are left positioned as they would be from the call:
+        initstate(1, randtbl, 128);
+   (The position of the rear pointer, rptr, is really 0 (as explained above
+   in the initialization of randtbl) because the state table pointer is set
+   to point to randtbl[1] (as explained below).)  */
+
+                .fptr = &randtbl[SEP_3 + 1],
+                .rptr = &randtbl[1],
+
+/* The following things are the pointer to the state information table,
+   the type of the current generator, the degree of the current polynomial
+   being used, and the separation between the two pointers.
+   Note that for efficiency of random, we remember the first location of
+   the state information, not the zeroth.  Hence it is valid to access
+   state[-1], which is used to store the type of the R.N.G.
+   Also, we remember the last location, since this is more efficient than
+   indexing every time to find the address of the last element to see if
+   the front and rear pointers have wrapped.  */
+
+                .state = &randtbl[1],
+
+                .rand_type = TYPE_3,
+                .rand_deg = DEG_3,
+                .rand_sep = SEP_3,
+
+                .end_ptr = &randtbl[sizeof (randtbl) / sizeof (randtbl[0])]
+        };
+
+/* POSIX.1c requires that there is mutual exclusion for the 'rand' and
+   'srand' functions to prevent concurrent calls from modifying common
+   data.  */
+__libc_lock_define_initialized (static, lock)
+
+/* Initialize the random number generator based on the given seed.  If the
+   type is the trivial no-state-information type, just remember the seed.
+   Otherwise, initializes state[] based on the given "seed" via a linear
+   congruential generator.  Then, the pointers are set to known locations
+   that are exactly rand_sep places apart.  Lastly, it cycles the state
+   information a given number of times to get rid of any initial dependencies
+   introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
+   for default usage relies on values produced by this routine.  */
+void
+__srandom (unsigned int x)
+{
+    __libc_lock_lock (lock);
+    (void) __srandom_r (x, &unsafe_state);
+    __libc_lock_unlock (lock);
+}
+
+inline void
+srandom (unsigned int x)
+{
+    return __srandom(x);
+}
+
+inline void
+srand (unsigned int x)
+{
+    return __srandom(x);
+}
+
+/* Initialize the state information in the given array of N bytes for
+   future random number generation.  Based on the number of bytes we
+   are given, and the break values for the different R.N.G.'s, we choose
+   the best (largest) one we can and set things up for it.  srandom is
+   then called to initialize the state information.  Note that on return
+   from srandom, we set state[-1] to be the type multiplexed with the current
+   value of the rear pointer; this is so successive calls to initstate won't
+   lose this information and will be able to restart with setstate.
+   Note: The first thing we do is save the current state, if any, just like
+   setstate so that it doesn't matter when initstate is called.
+   Returns a pointer to the old state.  */
+char *
+__initstate (unsigned int seed, char *arg_state, size_t n)
+{
+    int32_t *ostate;
+    int ret;
+
+    __libc_lock_lock (lock);
+
+    ostate = &unsafe_state.state[-1];
+
+    ret = __initstate_r (seed, arg_state, n, &unsafe_state);
+
+    __libc_lock_unlock (lock);
+
+    return ret == -1 ? NULL : (char *) ostate;
+}
+
+inline char *
+initstate (unsigned int seed, char *arg_state, size_t n)
+{
+    return __initstate(seed, arg_state, n);
+}
+
+/* Restore the state from the given state array.
+   Note: It is important that we also remember the locations of the pointers
+   in the current state information, and restore the locations of the pointers
+   from the old state information.  This is done by multiplexing the pointer
+   location into the zeroth word of the state information. Note that due
+   to the order in which things are done, it is OK to call setstate with the
+   same state as the current state
+   Returns a pointer to the old state information.  */
+char *
+__setstate (char *arg_state)
+{
+    int32_t *ostate;
+
+    __libc_lock_lock (lock);
+
+    ostate = &unsafe_state.state[-1];
+
+    if (__setstate_r (arg_state, &unsafe_state) < 0)
+        ostate = NULL;
+
+    __libc_lock_unlock (lock);
+
+    return (char *) ostate;
+}
+
+inline char *
+setstate (char *arg_state)
+{
+    return __setstate(arg_state);
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+   congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
+   same in all the other cases due to all the global variables that have been
+   set up.  The basic operation is to add the number at the rear pointer into
+   the one at the front pointer.  Then both pointers are advanced to the next
+   location cyclically in the table.  The value returned is the sum generated,
+   reduced to 31 bits by throwing away the "least random" low bit.
+   Note: The code takes advantage of the fact that both the front and
+   rear pointers can't wrap on the same call by not testing the rear
+   pointer if the front one has wrapped.  Returns a 31-bit random number.  */
+
+long int
+__random (void)
+{
+    int32_t retval;
+
+    __libc_lock_lock (lock);
+
+    (void) __random_r (&unsafe_state, &retval);
+
+    __libc_lock_unlock (lock);
+
+    return retval;
+}
+inline long int random(void)
+{
+    return __random();
+}
+
+/* Array versions of the above information to make code run faster.
+   Relies on fact that TYPE_i == i.  */
+
+struct random_poly_info
+{
+    int seps[MAX_TYPES];
+    int degrees[MAX_TYPES];
+};
+
+static const struct random_poly_info random_poly_info =
+        {
+                { SEP_0, SEP_1, SEP_2, SEP_3, SEP_4 },
+                { DEG_0, DEG_1, DEG_2, DEG_3, DEG_4 }
+        };
+
+static int32_t
+get_int32 (void *p)
+{
+    int32_t v;
+    memcpy (&v, p, sizeof v);
+    return v;
+}
+
+static void
+set_int32 (void *p, int32_t v)
+{
+    memcpy (p, &v, sizeof v);
+}
+
+
+/* Initialize the random number generator based on the given seed.  If the
+   type is the trivial no-state-information type, just remember the seed.
+   Otherwise, initializes state[] based on the given "seed" via a linear
+   congruential generator.  Then, the pointers are set to known locations
+   that are exactly rand_sep places apart.  Lastly, it cycles the state
+   information a given number of times to get rid of any initial dependencies
+   introduced by the L.C.R.N.G.  Note that the initialization of randtbl[]
+   for default usage relies on values produced by this routine.  */
+int
+__srandom_r (unsigned int seed, struct random_data *buf)
+{
+    int type;
+    int32_t *state;
+    long int i;
+    int32_t word;
+    int32_t *dst;
+    int kc;
+
+    if (buf == NULL)
+        goto fail;
+    type = buf->rand_type;
+    if ((unsigned int) type >= MAX_TYPES)
+        goto fail;
+
+    state = buf->state;
+    /* We must make sure the seed is not 0.  Take arbitrarily 1 in this case.  */
+    if (seed == 0)
+        seed = 1;
+    set_int32 (&state[0], seed);
+    if (type == TYPE_0)
+        goto done;
+
+    dst = state;
+    word = seed;
+    kc = buf->rand_deg;
+    for (i = 1; i < kc; ++i)
+    {
+        /* This does:
+             state[i] = (16807 * state[i - 1]) % 2147483647;
+           but avoids overflowing 31 bits.  */
+        long int hi = word / 127773;
+        long int lo = word % 127773;
+        word = 16807 * lo - 2836 * hi;
+        if (word < 0)
+            word += 2147483647;
+        set_int32 (++dst, word);
+    }
+
+    buf->fptr = &state[buf->rand_sep];
+    buf->rptr = &state[0];
+    kc *= 10;
+    while (--kc >= 0)
+    {
+        int32_t discard;
+        (void) __random_r (buf, &discard);
+    }
+
+    done:
+    return 0;
+
+    fail:
+    return -1;
+}
+
+inline int
+srandom_r (unsigned int seed, struct random_data *buf)
+{
+    return __srandom_r(seed, buf);
+}
+
+/* Initialize the state information in the given array of N bytes for
+   future random number generation.  Based on the number of bytes we
+   are given, and the break values for the different R.N.G.'s, we choose
+   the best (largest) one we can and set things up for it.  srandom is
+   then called to initialize the state information.  Note that on return
+   from srandom, we set state[-1] to be the type multiplexed with the current
+   value of the rear pointer; this is so successive calls to initstate won't
+   lose this information and will be able to restart with setstate.
+   Note: The first thing we do is save the current state, if any, just like
+   setstate so that it doesn't matter when initstate is called.
+   Returns 0 on success, non-zero on failure.  */
+int
+__initstate_r (unsigned int seed, char *arg_state, size_t n,
+               struct random_data *buf)
+{
+    if (buf == NULL)
+        goto fail;
+
+    int32_t *old_state = buf->state;
+    if (old_state != NULL)
+    {
+        int old_type = buf->rand_type;
+        set_int32 (&old_state[-1],
+                   (old_type == TYPE_0
+                    ? TYPE_0
+                    : (MAX_TYPES * (buf->rptr - old_state)) + old_type));
+    }
+
+    int type;
+    if (n >= BREAK_3)
+        type = n < BREAK_4 ? TYPE_3 : TYPE_4;
+    else if (n < BREAK_1)
+    {
+        if (n < BREAK_0)
+            goto fail;
+
+        type = TYPE_0;
+    }
+    else
+        type = n < BREAK_2 ? TYPE_1 : TYPE_2;
+
+    int degree = random_poly_info.degrees[type];
+    int separation = random_poly_info.seps[type];
+
+    buf->rand_type = type;
+    buf->rand_sep = separation;
+    buf->rand_deg = degree;
+    int32_t *state = &((int32_t *) arg_state)[1]; /* First location.  */
+    /* Must set END_PTR before srandom.  */
+    buf->end_ptr = &state[degree];
+
+    buf->state = state;
+
+    __srandom_r (seed, buf);
+
+    set_int32 (&state[-1],
+               type == TYPE_0 ? TYPE_0 : (buf->rptr - state) * MAX_TYPES + type);
+
+    return 0;
+
+    fail:
+    __set_errno (EINVAL);
+    return -1;
+}
+
+inline int
+initstate_r (unsigned int seed, char *arg_state, size_t n,
+               struct random_data *buf)
+{
+    return __initstate_r(seed, arg_state, n, buf);
+}
+
+/* Restore the state from the given state array.
+   Note: It is important that we also remember the locations of the pointers
+   in the current state information, and restore the locations of the pointers
+   from the old state information.  This is done by multiplexing the pointer
+   location into the zeroth word of the state information. Note that due
+   to the order in which things are done, it is OK to call setstate with the
+   same state as the current state
+   Returns 0 on success, non-zero on failure.  */
+int
+__setstate_r (char *arg_state, struct random_data *buf)
+{
+    int32_t *new_state = 1 + (int32_t *) arg_state;
+    int type;
+    int old_type;
+    int32_t *old_state;
+    int degree;
+    int separation;
+
+    if (arg_state == NULL || buf == NULL)
+        goto fail;
+
+    old_type = buf->rand_type;
+    old_state = buf->state;
+    set_int32 (&old_state[-1],
+               (old_type == TYPE_0
+                ? TYPE_0
+                : (MAX_TYPES * (buf->rptr - old_state)) + old_type));
+
+    type = get_int32 (&new_state[-1]) % MAX_TYPES;
+    if (type < TYPE_0 || type > TYPE_4)
+        goto fail;
+
+    buf->rand_deg = degree = random_poly_info.degrees[type];
+    buf->rand_sep = separation = random_poly_info.seps[type];
+    buf->rand_type = type;
+
+    if (type != TYPE_0)
+    {
+        int rear = get_int32 (&new_state[-1]) / MAX_TYPES;
+        buf->rptr = &new_state[rear];
+        buf->fptr = &new_state[(rear + separation) % degree];
+    }
+    buf->state = new_state;
+    /* Set end_ptr too.  */
+    buf->end_ptr = &new_state[degree];
+
+    return 0;
+
+    fail:
+    __set_errno (EINVAL);
+    return -1;
+}
+
+inline int setstate_r (char *arg_state, struct random_data *buf)
+{
+    return __setstate_r(arg_state, buf);
+}
+
+/* If we are using the trivial TYPE_0 R.N.G., just do the old linear
+   congruential bit.  Otherwise, we do our fancy trinomial stuff, which is the
+   same in all the other cases due to all the global variables that have been
+   set up.  The basic operation is to add the number at the rear pointer into
+   the one at the front pointer.  Then both pointers are advanced to the next
+   location cyclically in the table.  The value returned is the sum generated,
+   reduced to 31 bits by throwing away the "least random" low bit.
+   Note: The code takes advantage of the fact that both the front and
+   rear pointers can't wrap on the same call by not testing the rear
+   pointer if the front one has wrapped.  Returns a 31-bit random number.  */
+
+int
+__random_r (struct random_data *buf, int32_t *result)
+{
+    int32_t *state;
+
+    if (buf == NULL || result == NULL)
+        goto fail;
+
+    state = buf->state;
+
+    if (buf->rand_type == TYPE_0)
+    {
+        int32_t val = (((get_int32 (&state[0]) * 1103515245U) + 12345U)
+                       & 0x7fffffff);
+        set_int32 (&state[0], val);
+        *result = val;
+    }
+    else
+    {
+        int32_t *fptr = buf->fptr;
+        int32_t *rptr = buf->rptr;
+        int32_t *end_ptr = buf->end_ptr;
+        /* F and R are unsigned int, not uint32_t, to avoid undefined
+           overflow behavior on platforms where INT_MAX == UINT32_MAX.  */
+        unsigned int f = get_int32 (fptr);
+        unsigned int r = get_int32 (rptr);
+        uint32_t val = f + r;
+        set_int32 (fptr, val);
+        /* Chucking least random bit.  */
+        *result = val >> 1;
+        ++fptr;
+        if (fptr >= end_ptr)
+        {
+            fptr = state;
+            ++rptr;
+        }
+        else
+        {
+            ++rptr;
+            if (rptr >= end_ptr)
+                rptr = state;
+        }
+        buf->fptr = fptr;
+        buf->rptr = rptr;
+    }
+    return 0;
+
+    fail:
+    __set_errno (EINVAL);
+    return -1;
+}
+
+inline int
+random_r (struct random_data *buf, int32_t *result)
+{
+    return __random_r(buf, result);
+}
+
+#endif
+
 #if !defined(HAVE_GETCWD)
@@ -526,2 +1647,19 @@ strftime(char *buf, size_t len, const char *fmt, const struct tm *tm)

+#if !defined(HAVE_STRERROR)
+extern int errno, sys_nerr;
+extern char *sys_errlist[];
+
+char *
+strerror(int e)
+{
+    static char buf[100];
+    if (e < 0 || e >= sys_nerr) {
+        snprintf(buf, sizeof(buf), "Unknown error %d", e);
+        return buf;
+    }
+    else
+        return sys_errlist[e];
+}
+#endif
+
 #if !defined(HAVE_KILLPG)
@@ -599,11 +1737,11 @@ errx(int eval, const char *fmt, ...)

-#if !defined(HAVE_WARN)
-void
-warn(const char *fmt, ...)
-{
-        va_list ap;
+#if !defined(HAVE_KILL) && (defined _WIN32 && ! defined __CYGWIN__)
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>

-        va_start(ap, fmt);
-        vwarn(fmt, ap);
-        va_end(ap);
+/* The return value of spawnvp() is really a process handle as returned
+   by CreateProcess().  Therefore we can kill it using TerminateProcess.  */
+int kill(pid_t pid, int sig)
+{
+    return TerminateProcess ((HANDLE) (pid), sig);
 }
@@ -611,9 +1749,1208 @@ warn(const char *fmt, ...)

-#if !defined(HAVE_WARNX)
-void
-warnx(const char *fmt, ...)
-{
-        va_list ap;
+#if (defined _WIN32 && ! defined __CYGWIN__) //poll function
+/* Emulation for poll(2)
+   Contributed by Paolo Bonzini.

-        va_start(ap, fmt);
+   Copyright 2001-2003, 2006-2018 Free Software Foundation, Inc.
+
+   This file is part of gnulib.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License along
+   with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+/* Tell gcc not to warn about the (nfd < 0) tests, below.  */
+#if (__GNUC__ == 4 && 3 <= __GNUC_MINOR__) || 4 < __GNUC__
+# pragma GCC diagnostic ignored "-Wtype-limits"
+#endif
+
+//#include <alloca.h>
+
+#include <sys/types.h>
+
+/* Specification.  */
+#include "headers-mingw/poll.h"
+
+#include <errno.h>
+#include <limits.h>
+
+#include <winsock2.h>
+#include <windows.h>
+#include <io.h>
+#include <stdio.h>
+#include <conio.h>
+#if GNULIB_MSVC_NOTHROW
+# include "msvc-nothrow.h"
+#else
+# include <io.h>
+#endif
+
+//#include <sys/select.h>
+//#include <sys/socket.h>
+
+#ifdef HAVE_SYS_IOCTL_H
+# include <sys/ioctl.h>
+#endif
+#ifdef HAVE_SYS_FILIO_H
+# include <sys/filio.h>
+#endif
+
+#include <time.h>
+
+//#include "assure.h"
+
+#ifndef INFTIM
+# define INFTIM (-1)
+#endif
+
+/* BeOS does not have MSG_PEEK.  */
+#ifndef MSG_PEEK
+# define MSG_PEEK 0
+#endif
+
+/* Avoid warnings from gcc -Wcast-function-type.  */
+# define GetProcAddress \
+   (void *) GetProcAddress
+
+static BOOL IsConsoleHandle (HANDLE h)
+{
+  DWORD mode;
+  return GetConsoleMode (h, &mode) != 0;
+}
+
+static BOOL
+IsSocketHandle (HANDLE h)
+{
+  WSANETWORKEVENTS ev;
+
+  if (IsConsoleHandle (h))
+    return FALSE;
+
+  /* Under Wine, it seems that getsockopt returns 0 for pipes too.
+     WSAEnumNetworkEvents instead distinguishes the two correctly.  */
+  ev.lNetworkEvents = 0xDEADBEEF;
+  WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
+  return ev.lNetworkEvents != 0xDEADBEEF;
+}
+
+typedef DWORD (WINAPI *PNtQueryInformationFile)
+         (HANDLE, IO_STATUS_BLOCK *, VOID *, ULONG, FILE_INFORMATION_CLASS);
+
+# ifndef PIPE_BUF
+#  define PIPE_BUF      512
+# endif
+
+/* Compute revents values for file handle H.  If some events cannot happen
+   for the handle, eliminate them from *P_SOUGHT.  */
+
+static int
+windows_compute_revents (HANDLE h, int *p_sought)
+{
+  int i, ret, happened;
+  INPUT_RECORD *irbuffer;
+  DWORD avail, nbuffer;
+  BOOL bRet;
+  IO_STATUS_BLOCK iosb;
+  FILE_PIPE_LOCAL_INFORMATION fpli;
+  static PNtQueryInformationFile NtQueryInformationFile;
+  static BOOL once_only;
+
+  switch (GetFileType (h))
+    {
+    case FILE_TYPE_PIPE:
+      if (!once_only)
+        {
+          NtQueryInformationFile = (PNtQueryInformationFile)
+            GetProcAddress (GetModuleHandle ("ntdll.dll"),
+                            "NtQueryInformationFile");
+          once_only = TRUE;
+        }
+
+      happened = 0;
+      if (PeekNamedPipe (h, NULL, 0, NULL, &avail, NULL) != 0)
+        {
+          if (avail)
+            happened |= *p_sought & (POLLIN | POLLRDNORM);
+        }
+      else if (GetLastError () == ERROR_BROKEN_PIPE)
+        happened |= POLLHUP;
+
+      else
+        {
+          /* It was the write-end of the pipe.  Check if it is writable.
+             If NtQueryInformationFile fails, optimistically assume the pipe is
+             writable.  This could happen on Windows 9x, where
+             NtQueryInformationFile is not available, or if we inherit a pipe
+             that doesn't permit FILE_READ_ATTRIBUTES access on the write end
+             (I think this should not happen since Windows XP SP2; WINE seems
+             fine too).  Otherwise, ensure that enough space is available for
+             atomic writes.  */
+          memset (&iosb, 0, sizeof (iosb));
+          memset (&fpli, 0, sizeof (fpli));
+
+          if (!NtQueryInformationFile
+              || NtQueryInformationFile (h, &iosb, &fpli, sizeof (fpli),
+                                         FilePipeLocalInformation)
+              || fpli.WriteQuotaAvailable >= PIPE_BUF
+              || (fpli.OutboundQuota < PIPE_BUF &&
+                  fpli.WriteQuotaAvailable == fpli.OutboundQuota))
+            happened |= *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
+        }
+      return happened;
+
+    case FILE_TYPE_CHAR:
+      ret = WaitForSingleObject (h, 0);
+      if (!IsConsoleHandle (h))
+        return ret == WAIT_OBJECT_0 ? *p_sought & ~(POLLPRI | POLLRDBAND) : 0;
+
+      nbuffer = avail = 0;
+      bRet = GetNumberOfConsoleInputEvents (h, &nbuffer);
+      if (bRet)
+        {
+          /* Input buffer.  */
+          *p_sought &= POLLIN | POLLRDNORM;
+          if (nbuffer == 0)
+            return POLLHUP;
+          if (!*p_sought)
+            return 0;
+
+          irbuffer = (INPUT_RECORD *) alloca (nbuffer * sizeof (INPUT_RECORD));
+          bRet = PeekConsoleInput (h, irbuffer, nbuffer, &avail);
+          if (!bRet || avail == 0)
+            return POLLHUP;
+
+          for (i = 0; i < avail; i++)
+            if (irbuffer[i].EventType == KEY_EVENT)
+              return *p_sought;
+          return 0;
+        }
+      else
+        {
+          /* Screen buffer.  */
+          *p_sought &= POLLOUT | POLLWRNORM | POLLWRBAND;
+          return *p_sought;
+        }
+
+    default:
+      ret = WaitForSingleObject (h, 0);
+      if (ret == WAIT_OBJECT_0)
+        return *p_sought & ~(POLLPRI | POLLRDBAND);
+
+      return *p_sought & (POLLOUT | POLLWRNORM | POLLWRBAND);
+    }
+}
+
+/* Convert fd_sets returned by select into revents values.  */
+
+static int
+windows_compute_revents_socket (SOCKET h, int sought, long lNetworkEvents)
+{
+  int happened = 0;
+
+  if ((lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE)) == FD_ACCEPT)
+    happened |= (POLLIN | POLLRDNORM) & sought;
+
+  else if (lNetworkEvents & (FD_READ | FD_ACCEPT | FD_CLOSE))
+    {
+      int r, error;
+
+      char data[64];
+      WSASetLastError (0);
+      r = recv (h, data, sizeof (data), MSG_PEEK);
+      error = WSAGetLastError ();
+      WSASetLastError (0);
+
+      if (r > 0 || error == WSAENOTCONN)
+        happened |= (POLLIN | POLLRDNORM) & sought;
+
+      /* Distinguish hung-up sockets from other errors.  */
+      else if (r == 0 || error == WSAESHUTDOWN || error == WSAECONNRESET
+               || error == WSAECONNABORTED || error == WSAENETRESET)
+        happened |= POLLHUP;
+
+      else
+        happened |= POLLERR;
+    }
+
+  if (lNetworkEvents & (FD_WRITE | FD_CONNECT))
+    happened |= (POLLOUT | POLLWRNORM | POLLWRBAND) & sought;
+
+  if (lNetworkEvents & FD_OOB)
+    happened |= (POLLPRI | POLLRDBAND) & sought;
+
+  return happened;
+}
+
+int
+poll (struct pollfd *pfd, nfds_t nfd, int timeout)
+{
+  static struct timeval tv0;
+  static HANDLE hEvent;
+  WSANETWORKEVENTS ev;
+  HANDLE h, handle_array[FD_SETSIZE + 2];
+  DWORD ret, wait_timeout, nhandles;
+  fd_set rfds, wfds, xfds;
+  BOOL poll_again;
+  MSG msg;
+  int rc = 0;
+  nfds_t i;
+
+  if (nfd > INT_MAX || timeout < -1)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  if (!hEvent)
+    hEvent = CreateEvent (NULL, FALSE, FALSE, NULL);
+
+restart:
+  handle_array[0] = hEvent;
+  nhandles = 1;
+  FD_ZERO (&rfds);
+  FD_ZERO (&wfds);
+  FD_ZERO (&xfds);
+
+  /* Classify socket handles and create fd sets. */
+  for (i = 0; i < nfd; i++)
+    {
+      int sought = pfd[i].events;
+      pfd[i].revents = 0;
+      if (pfd[i].fd < 0)
+        continue;
+      if (!(sought & (POLLIN | POLLRDNORM | POLLOUT | POLLWRNORM | POLLWRBAND
+                      | POLLPRI | POLLRDBAND)))
+        continue;
+
+      h = (HANDLE) _get_osfhandle (pfd[i].fd);
+      if (IsSocketHandle (h))
+        {
+          int requested = FD_CLOSE;
+
+          /* see above; socket handles are mapped onto select.  */
+          if (sought & (POLLIN | POLLRDNORM))
+            {
+              requested |= FD_READ | FD_ACCEPT;
+              FD_SET ((SOCKET) h, &rfds);
+            }
+          if (sought & (POLLOUT | POLLWRNORM | POLLWRBAND))
+            {
+              requested |= FD_WRITE | FD_CONNECT;
+              FD_SET ((SOCKET) h, &wfds);
+            }
+          if (sought & (POLLPRI | POLLRDBAND))
+            {
+              requested |= FD_OOB;
+              FD_SET ((SOCKET) h, &xfds);
+            }
+
+          if (requested)
+            WSAEventSelect ((SOCKET) h, hEvent, requested);
+        }
+      else
+        {
+          /* Poll now.  If we get an event, do not poll again.  Also,
+             screen buffer handles are waitable, and they'll block until
+             a character is available.  windows_compute_revents eliminates
+             bits for the "wrong" direction. */
+          pfd[i].revents = windows_compute_revents (h, &sought);
+          if (sought)
+            handle_array[nhandles++] = h;
+          if (pfd[i].revents)
+            timeout = 0;
+        }
+    }
+
+  if (select (0, &rfds, &wfds, &xfds, &tv0) > 0)
+    {
+      /* Do MsgWaitForMultipleObjects anyway to dispatch messages, but
+         no need to call select again.  */
+      poll_again = FALSE;
+      wait_timeout = 0;
+    }
+  else
+    {
+      poll_again = TRUE;
+      if (timeout == INFTIM)
+        wait_timeout = INFINITE;
+      else
+        wait_timeout = timeout;
+    }
+
+  for (;;)
+    {
+      ret = MsgWaitForMultipleObjects (nhandles, handle_array, FALSE,
+                                       wait_timeout, QS_ALLINPUT);
+
+      if (ret == WAIT_OBJECT_0 + nhandles)
+        {
+          /* new input of some other kind */
+          BOOL bRet;
+          while ((bRet = PeekMessage (&msg, NULL, 0, 0, PM_REMOVE)) != 0)
+            {
+              TranslateMessage (&msg);
+              DispatchMessage (&msg);
+            }
+        }
+      else
+        break;
+    }
+
+  if (poll_again)
+    select (0, &rfds, &wfds, &xfds, &tv0);
+
+  /* Place a sentinel at the end of the array.  */
+  handle_array[nhandles] = NULL;
+  nhandles = 1;
+  for (i = 0; i < nfd; i++)
+    {
+      int happened;
+
+      if (pfd[i].fd < 0)
+        continue;
+      if (!(pfd[i].events & (POLLIN | POLLRDNORM |
+                             POLLOUT | POLLWRNORM | POLLWRBAND)))
+        continue;
+
+      h = (HANDLE) _get_osfhandle (pfd[i].fd);
+      if (h != handle_array[nhandles])
+        {
+          /* It's a socket.  */
+          WSAEnumNetworkEvents ((SOCKET) h, NULL, &ev);
+          WSAEventSelect ((SOCKET) h, 0, 0);
+
+          /* If we're lucky, WSAEnumNetworkEvents already provided a way
+             to distinguish FD_READ and FD_ACCEPT; this saves a recv later.  */
+          if (FD_ISSET ((SOCKET) h, &rfds)
+              && !(ev.lNetworkEvents & (FD_READ | FD_ACCEPT)))
+            ev.lNetworkEvents |= FD_READ | FD_ACCEPT;
+          if (FD_ISSET ((SOCKET) h, &wfds))
+            ev.lNetworkEvents |= FD_WRITE | FD_CONNECT;
+          if (FD_ISSET ((SOCKET) h, &xfds))
+            ev.lNetworkEvents |= FD_OOB;
+
+          happened = windows_compute_revents_socket ((SOCKET) h, pfd[i].events,
+                                                     ev.lNetworkEvents);
+        }
+      else
+        {
+          /* Not a socket.  */
+          int sought = pfd[i].events;
+          happened = windows_compute_revents (h, &sought);
+          nhandles++;
+        }
+
+       if ((pfd[i].revents |= happened) != 0)
+        rc++;
+    }
+
+  if (!rc && timeout == INFTIM)
+    {
+      SleepEx (1, TRUE);
+      goto restart;
+    }
+
+  return rc;
+}
+
+#endif //(defined _WIN32 && ! defined __CYGWIN__) (poll function)
+
+#if !defined(HAVE_SIGEMPTYSET) || !defined(HAVE_SIGISMEMBER) || !defined(HAVE_SIGPROCMASK) || !defined(HAVE_SIGACTION)
+/* POSIX compatible signal blocking.
+   Copyright (C) 2006-2018 Free Software Foundation, Inc.
+   Written by Bruno Haible <bruno@clisp.org>, 2006.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Specification.  */
+#include <signal.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/signal.h"
+#endif
+
+#include <errno.h>
+#include <stdint.h>
+#include <stdlib.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/stdlib.h"
+#endif
+
+#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+# include "msvc-inval.h"
+#endif
+
+/* We assume that a platform without POSIX signal blocking functions
+   also does not have the POSIX sigaction() function, only the
+   signal() function.  We also assume signal() has SysV semantics,
+   where any handler is uninstalled prior to being invoked.  This is
+   true for native Windows platforms.  */
+
+/* We use raw signal(), but also provide a wrapper rpl_signal() so
+   that applications can query or change a blocked signal.  */
+#undef signal
+
+/* Provide invalid signal numbers as fallbacks if the uncatchable
+   signals are not defined.  */
+#ifndef SIGKILL
+# define SIGKILL (-1)
+#endif
+#ifndef SIGSTOP
+# define SIGSTOP (-1)
+#endif
+
+/* On native Windows, as of 2008, the signal SIGABRT_COMPAT is an alias
+   for the signal SIGABRT.  Only one signal handler is stored for both
+   SIGABRT and SIGABRT_COMPAT.  SIGABRT_COMPAT is not a signal of its own.  */
+#if defined _WIN32 && ! defined __CYGWIN__
+# undef SIGABRT_COMPAT
+# define SIGABRT_COMPAT 6
+#endif
+#ifdef SIGABRT_COMPAT
+# define SIGABRT_COMPAT_MASK (1U << SIGABRT_COMPAT)
+#else
+# define SIGABRT_COMPAT_MASK 0
+#endif
+
+typedef void (*handler_t) (int);
+
+#if HAVE_MSVC_INVALID_PARAMETER_HANDLER
+static handler_t
+signal_nothrow (int sig, handler_t handler)
+{
+  handler_t result;
+
+  TRY_MSVC_INVAL
+    {
+      result = signal (sig, handler);
+    }
+  CATCH_MSVC_INVAL
+    {
+      result = SIG_ERR;
+      errno = EINVAL;
+    }
+  DONE_MSVC_INVAL;
+
+  return result;
+}
+# define signal signal_nothrow
+#endif
+
+/* Handling of gnulib defined signals.  */
+
+#if GNULIB_defined_SIGPIPE
+static handler_t SIGPIPE_handler = SIG_DFL;
+#endif
+
+#if GNULIB_defined_SIGPIPE
+static handler_t
+ext_signal (int sig, handler_t handler)
+{
+  switch (sig)
+    {
+    case SIGPIPE:
+      {
+        handler_t old_handler = SIGPIPE_handler;
+        SIGPIPE_handler = handler;
+        return old_handler;
+      }
+    default: /* System defined signal */
+      return signal (sig, handler);
+    }
+}
+# undef signal
+# define signal ext_signal
+#endif
+
+int
+sigismember (const sigset_t *set, int sig)
+{
+    if (sig >= 0 && sig < NSIG)
+    {
+#ifdef SIGABRT_COMPAT
+        if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+#endif
+
+        return (*set >> sig) & 1;
+    }
+    else
+        return 0;
+}
+
+int
+sigemptyset (sigset_t *set)
+{
+    *set = 0;
+    return 0;
+}
+
+int
+sigaddset (sigset_t *set, int sig)
+{
+    if (sig >= 0 && sig < NSIG)
+    {
+#ifdef SIGABRT_COMPAT
+        if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+#endif
+
+        *set |= 1U << sig;
+        return 0;
+    }
+    else
+    {
+        errno = EINVAL;
+        return -1;
+    }
+}
+
+int
+sigdelset (sigset_t *set, int sig)
+{
+    if (sig >= 0 && sig < NSIG)
+    {
+#ifdef SIGABRT_COMPAT
+        if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+#endif
+
+        *set &= ~(1U << sig);
+        return 0;
+    }
+    else
+    {
+        errno = EINVAL;
+        return -1;
+    }
+}
+
+
+int
+sigfillset (sigset_t *set)
+{
+    *set = ((2U << (NSIG - 1)) - 1) & ~ SIGABRT_COMPAT_MASK;
+    return 0;
+}
+
+/* Set of currently blocked signals.  */
+static volatile sigset_t blocked_set /* = 0 */;
+
+/* Set of currently blocked and pending signals.  */
+static volatile sig_atomic_t pending_array[NSIG] /* = { 0 } */;
+
+/* Signal handler that is installed for blocked signals.  */
+static void
+blocked_handler (int sig)
+{
+    /* Reinstall the handler, in case the signal occurs multiple times
+       while blocked.  There is an inherent race where an asynchronous
+       signal in between when the kernel uninstalled the handler and
+       when we reinstall it will trigger the default handler; oh
+       well.  */
+    signal (sig, blocked_handler);
+    if (sig >= 0 && sig < NSIG)
+        pending_array[sig] = 1;
+}
+
+int
+sigpending (sigset_t *set)
+{
+    sigset_t pending = 0;
+    int sig;
+
+    for (sig = 0; sig < NSIG; sig++)
+        if (pending_array[sig])
+            pending |= 1U << sig;
+    *set = pending;
+    return 0;
+}
+
+/* The previous signal handlers.
+   Only the array elements corresponding to blocked signals are relevant.  */
+static volatile handler_t old_handlers[NSIG];
+
+int
+sigprocmask (int operation, const sigset_t *set, sigset_t *old_set)
+{
+    if (old_set != NULL)
+        *old_set = blocked_set;
+
+    if (set != NULL)
+    {
+        sigset_t new_blocked_set;
+        sigset_t to_unblock;
+        sigset_t to_block;
+
+        switch (operation)
+        {
+            case SIG_BLOCK:
+                new_blocked_set = blocked_set | *set;
+                break;
+            case SIG_SETMASK:
+                new_blocked_set = *set;
+                break;
+            case SIG_UNBLOCK:
+                new_blocked_set = blocked_set & ~*set;
+                break;
+            default:
+                errno = EINVAL;
+                return -1;
+        }
+        to_unblock = blocked_set & ~new_blocked_set;
+        to_block = new_blocked_set & ~blocked_set;
+
+        if (to_block != 0)
+        {
+            int sig;
+
+            for (sig = 0; sig < NSIG; sig++)
+                if ((to_block >> sig) & 1)
+                {
+                    pending_array[sig] = 0;
+                    if ((old_handlers[sig] = signal (sig, blocked_handler)) != SIG_ERR)
+                        blocked_set |= 1U << sig;
+                }
+        }
+
+        if (to_unblock != 0)
+        {
+            sig_atomic_t received[NSIG];
+            int sig;
+
+            for (sig = 0; sig < NSIG; sig++)
+                if ((to_unblock >> sig) & 1)
+                {
+//                    if (signal (sig, old_handlers[sig]) != blocked_handler)
+//                        /* The application changed a signal handler while the signal
+//                           was blocked, bypassing our rpl_signal replacement.
+//                           We don't support this.  */
+//                        abort ();
+                    received[sig] = pending_array[sig];
+                    blocked_set &= ~(1U << sig);
+                    pending_array[sig] = 0;
+                }
+                else
+                    received[sig] = 0;
+
+            for (sig = 0; sig < NSIG; sig++)
+                if (received[sig])
+                    raise (sig);
+        }
+    }
+    return 0;
+}
+
+/* Install the handler FUNC for signal SIG, and return the previous
+   handler.  */
+handler_t
+rpl_signal (int sig, handler_t handler)
+{
+    /* We must provide a wrapper, so that a user can query what handler
+       they installed even if that signal is currently blocked.  */
+    if (sig >= 0 && sig < NSIG && sig != SIGKILL && sig != SIGSTOP
+        && handler != SIG_ERR)
+    {
+#ifdef SIGABRT_COMPAT
+        if (sig == SIGABRT_COMPAT)
+        sig = SIGABRT;
+#endif
+
+        if (blocked_set & (1U << sig))
+        {
+            /* POSIX states that sigprocmask and signal are both
+               async-signal-safe.  This is not true of our
+               implementation - there is a slight data race where an
+               asynchronous interrupt on signal A can occur after we
+               install blocked_handler but before we have updated
+               old_handlers for signal B, such that handler A can see
+               stale information if it calls signal(B).  Oh well -
+               signal handlers really shouldn't try to manipulate the
+               installed handlers of unrelated signals.  */
+            handler_t result = old_handlers[sig];
+            old_handlers[sig] = handler;
+            return result;
+        }
+        else
+            return signal (sig, handler);
+    }
+    else
+    {
+        errno = EINVAL;
+        return SIG_ERR;
+    }
+}
+
+/* This implementation of sigaction is tailored to native Windows behavior:
+   signal() has SysV semantics (ie. the handler is uninstalled before
+   it is invoked).  This is an inherent data race if an asynchronous
+   signal is sent twice in a row before we can reinstall our handler,
+   but there's nothing we can do about it.  Meanwhile, sigprocmask()
+   is not present, and while we can use the gnulib replacement to
+   provide critical sections, it too suffers from potential data races
+   in the face of an ill-timed asynchronous signal.  And we compound
+   the situation by reading static storage in a signal handler, which
+   POSIX warns is not generically async-signal-safe.  Oh well.
+
+   Additionally:
+     - We don't implement SA_NOCLDSTOP or SA_NOCLDWAIT, because SIGCHLD
+       is not defined.
+     - We don't implement SA_ONSTACK, because sigaltstack() is not present.
+     - We ignore SA_RESTART, because blocking native Windows API calls are
+       not interrupted anyway when an asynchronous signal occurs, and the
+       MSVCRT runtime never sets errno to EINTR.
+     - We don't implement SA_SIGINFO because it is impossible to do so
+       portably.
+
+   POSIX states that an application should not mix signal() and
+   sigaction().  We support the use of signal() within the gnulib
+   sigprocmask() substitute, but all other application code linked
+   with this module should stick with only sigaction().  */
+
+/* Set of current actions.  If sa_handler for an entry is NULL, then
+   that signal is not currently handled by the sigaction handler.  */
+static struct sigaction volatile action_array[NSIG] /* = 0 */;
+
+/* Signal handler that is installed for signals.  */
+static void
+sigaction_handler (int sig)
+{
+    handler_t handler;
+    sigset_t mask;
+    sigset_t oldmask;
+    int saved_errno = errno;
+    if (sig < 0 || NSIG <= sig || !action_array[sig].sa_handler)
+    {
+        /* Unexpected situation; be careful to avoid recursive abort.  */
+        if (sig == SIGABRT)
+            signal (SIGABRT, SIG_DFL);
+        abort ();
+    }
+
+    /* Reinstall the signal handler when required; otherwise update the
+       bookkeeping so that the user's handler may call sigaction and get
+       accurate results.  We know the signal isn't currently blocked, or
+       we wouldn't be in its handler, therefore we know that we are not
+       interrupting a sigaction() call.  There is a race where any
+       asynchronous instance of the same signal occurring before we
+       reinstall the handler will trigger the default handler; oh
+       well.  */
+    handler = action_array[sig].sa_handler;
+    if ((action_array[sig].sa_flags & SA_RESETHAND) == 0)
+        signal (sig, sigaction_handler);
+    else
+        action_array[sig].sa_handler = NULL;
+
+    /* Block appropriate signals.  */
+    mask = action_array[sig].sa_mask;
+    if ((action_array[sig].sa_flags & SA_NODEFER) == 0)
+        sigaddset (&mask, sig);
+    sigprocmask (SIG_BLOCK, &mask, &oldmask);
+
+    /* Invoke the user's handler, then restore prior mask.  */
+    errno = saved_errno;
+    handler (sig);
+    saved_errno = errno;
+    sigprocmask (SIG_SETMASK, &oldmask, NULL);
+    errno = saved_errno;
+}
+
+/* Change and/or query the action that will be taken on delivery of
+   signal SIG.  If not NULL, ACT describes the new behavior.  If not
+   NULL, OACT is set to the prior behavior.  Return 0 on success, or
+   set errno and return -1 on failure.  */
+int
+sigaction (int sig, const struct sigaction *restrict act,
+           struct sigaction *restrict oact)
+{
+    sigset_t mask;
+    sigset_t oldmask;
+    int saved_errno;
+
+    if (sig < 0 || NSIG <= sig || sig == SIGKILL || sig == SIGSTOP
+        || (act && act->sa_handler == SIG_ERR))
+    {
+        errno = EINVAL;
+        return -1;
+    }
+
+#ifdef SIGABRT_COMPAT
+    if (sig == SIGABRT_COMPAT)
+    sig = SIGABRT;
+#endif
+
+    /* POSIX requires sigaction() to be async-signal-safe.  In other
+       words, if an asynchronous signal can occur while we are anywhere
+       inside this function, the user's handler could then call
+       sigaction() recursively and expect consistent results.  We meet
+       this rule by using sigprocmask to block all signals before
+       modifying any data structure that could be read from a signal
+       handler; this works since we know that the gnulib sigprocmask
+       replacement does not try to use sigaction() from its handler.  */
+    if (!act && !oact)
+        return 0;
+    sigfillset (&mask);
+    sigprocmask (SIG_BLOCK, &mask, &oldmask);
+    if (oact)
+    {
+        if (action_array[sig].sa_handler)
+            *oact = action_array[sig];
+        else
+        {
+            /* Safe to change the handler at will here, since all
+               signals are currently blocked.  */
+            oact->sa_handler = signal (sig, SIG_DFL);
+            if (oact->sa_handler == SIG_ERR)
+                goto failure;
+            signal (sig, oact->sa_handler);
+            oact->sa_flags = SA_RESETHAND | SA_NODEFER;
+            sigemptyset (&oact->sa_mask);
+        }
+    }
+
+    if (act)
+    {
+        /* Safe to install the handler before updating action_array,
+           since all signals are currently blocked.  */
+        if (act->sa_handler == SIG_DFL || act->sa_handler == SIG_IGN)
+        {
+            if (signal (sig, act->sa_handler) == SIG_ERR)
+                goto failure;
+            action_array[sig].sa_handler = NULL;
+        }
+        else
+        {
+            if (signal (sig, sigaction_handler) == SIG_ERR)
+                goto failure;
+            action_array[sig] = *act;
+        }
+    }
+    sigprocmask (SIG_SETMASK, &oldmask, NULL);
+    return 0;
+
+    failure:
+    saved_errno = errno;
+    sigprocmask (SIG_SETMASK, &oldmask, NULL);
+    errno = saved_errno;
+    return -1;
+}
+
+#endif
+
+#if !defined(HAVE_UNAME)
+/* uname replacement.
+   Copyright (C) 2009-2018 Free Software Foundation, Inc.
+
+   This program is free software: you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 3 of the License, or
+   (at your option) any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
+
+/* Specification.  */
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/sys_utsname.h"
+#else
+#include <sys/utsname.h>
+#endif
+
+
+/* This file provides an implementation only for the native Windows API.  */
+
+#include <stdio.h>
+#include <stdlib.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/stdlib.h"
+#endif
+#include <string.h>
+#include <unistd.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/unistd.h"
+#endif
+#include <windows.h>
+
+/* Mingw headers don't have all the platform codes.  */
+#ifndef VER_PLATFORM_WIN32_CE
+# define VER_PLATFORM_WIN32_CE 3
+#endif
+
+/* Some headers don't have all the processor architecture codes.  */
+#ifndef PROCESSOR_ARCHITECTURE_AMD64
+# define PROCESSOR_ARCHITECTURE_AMD64 9
+#endif
+#ifndef PROCESSOR_ARCHITECTURE_IA32_ON_WIN64
+# define PROCESSOR_ARCHITECTURE_IA32_ON_WIN64 10
+#endif
+
+/* Mingw headers don't have the latest processor codes.  */
+#ifndef PROCESSOR_AMD_X8664
+# define PROCESSOR_AMD_X8664 8664
+#endif
+
+int
+uname (struct utsname *buf)
+{
+  OSVERSIONINFO version;
+  OSVERSIONINFOEX versionex;
+  BOOL have_versionex; /* indicates whether versionex is filled */
+  const char *super_version;
+
+  /* Preparation: Fill version and, if possible, also versionex.
+     But try to call GetVersionEx only once in the common case.  */
+  versionex.dwOSVersionInfoSize = sizeof (OSVERSIONINFOEX);
+  have_versionex = GetVersionEx ((OSVERSIONINFO *) &versionex);
+  if (have_versionex)
+    {
+      /* We know that OSVERSIONINFO is a subset of OSVERSIONINFOEX.  */
+      memcpy (&version, &versionex, sizeof (OSVERSIONINFO));
+    }
+  else
+    {
+      version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
+      if (!GetVersionEx (&version))
+        abort ();
+    }
+
+  /* Fill in nodename.  */
+  if (gethostname (buf->nodename, sizeof (buf->nodename)) < 0)
+    strcpy (buf->nodename, "localhost");
+
+  /* Determine major-major Windows version.  */
+  if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
+    {
+      /* Windows NT or newer.  */
+      super_version = "NT";
+    }
+  else if (version.dwPlatformId == VER_PLATFORM_WIN32_CE)
+    {
+      /* Windows CE or Embedded CE.  */
+      super_version = "CE";
+    }
+  else if (version.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS)
+    {
+      /* Windows 95/98/ME.  */
+      switch (version.dwMinorVersion)
+        {
+        case 0:
+          super_version = "95";
+          break;
+        case 10:
+          super_version = "98";
+          break;
+        case 90:
+          super_version = "ME";
+          break;
+        default:
+          super_version = "";
+          break;
+        }
+    }
+  else
+    super_version = "";
+
+  /* Fill in sysname.  */
+#ifdef __MINGW32__
+  /* Returns a string compatible with the MSYS uname.exe program,
+     so that no further changes are needed to GNU config.guess.
+     For example,
+       $ ./uname.exe -s      => MINGW32_NT-5.1
+   */
+  sprintf (buf->sysname, "MINGW32_%s-%u.%u", super_version,
+           (unsigned int) version.dwMajorVersion,
+           (unsigned int) version.dwMinorVersion);
+#else
+  sprintf (buf->sysname, "Windows%s", super_version);
+#endif
+
+  /* Fill in release, version.  */
+  /* The MSYS uname.exe programs uses strings from a modified Cygwin runtime:
+       $ ./uname.exe -r      => 1.0.11(0.46/3/2)
+       $ ./uname.exe -v      => 2008-08-25 23:40
+     There is no point in imitating this behaviour.  */
+  if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
+    {
+      /* Windows NT or newer.  */
+      struct windows_version
+        {
+          int major;
+          int minor;
+          unsigned int server_offset;
+          const char *name;
+        };
+
+      /* Storing the workstation and server version names in a single
+         stream does not waste memory when they are the same.  These
+         macros abstract the representation.  VERSION1 is used if
+         version.wProductType does not matter, VERSION2 if it does.  */
+      #define VERSION1(major, minor, name) \
+        { major, minor, 0, name }
+      #define VERSION2(major, minor, workstation, server) \
+        { major, minor, sizeof workstation, workstation "\0" server }
+      static const struct windows_version versions[] =
+        {
+          VERSION2 (3, -1, "Windows NT Workstation", "Windows NT Server"),
+          VERSION2 (4, -1, "Windows NT Workstation", "Windows NT Server"),
+          VERSION1 (5, 0, "Windows 2000"),
+          VERSION1 (5, 1, "Windows XP"),
+          VERSION1 (5, 2, "Windows Server 2003"),
+          VERSION2 (6, 0, "Windows Vista", "Windows Server 2008"),
+          VERSION2 (6, 1, "Windows 7", "Windows Server 2008 R2"),
+          VERSION2 (-1, -1, "Windows", "Windows Server")
+        };
+      const char *base;
+      const struct windows_version *v = versions;
+
+      /* Find a version that matches ours.  The last element is a
+         wildcard that always ends the loop.  */
+      while ((v->major != version.dwMajorVersion && v->major != -1)
+             || (v->minor != version.dwMinorVersion && v->minor != -1))
+        v++;
+
+      if (have_versionex && versionex.wProductType != VER_NT_WORKSTATION)
+        base = v->name + v->server_offset;
+      else
+        base = v->name;
+      if (v->major == -1 || v->minor == -1)
+        sprintf (buf->release, "%s %u.%u",
+                 base,
+                 (unsigned int) version.dwMajorVersion,
+                 (unsigned int) version.dwMinorVersion);
+      else
+        strcpy (buf->release, base);
+    }
+  else if (version.dwPlatformId == VER_PLATFORM_WIN32_CE)
+    {
+      /* Windows CE or Embedded CE.  */
+      sprintf (buf->release, "Windows CE %u.%u",
+               (unsigned int) version.dwMajorVersion,
+               (unsigned int) version.dwMinorVersion);
+    }
+  else
+    {
+      /* Windows 95/98/ME.  */
+      sprintf (buf->release, "Windows %s", super_version);
+    }
+  strcpy (buf->version, version.szCSDVersion);
+
+  /* Fill in machine.  */
+  {
+    SYSTEM_INFO info;
+
+    GetSystemInfo (&info);
+    /* Check for Windows NT or CE, since the info.wProcessorLevel is
+       garbage on Windows 95. */
+    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT
+        || version.dwPlatformId == VER_PLATFORM_WIN32_CE)
+      {
+        /* Windows NT or newer, or Windows CE or Embedded CE.  */
+        switch (info.wProcessorArchitecture)
+          {
+          case PROCESSOR_ARCHITECTURE_AMD64:
+            strcpy (buf->machine, "x86_64");
+            break;
+          case PROCESSOR_ARCHITECTURE_IA64:
+            strcpy (buf->machine, "ia64");
+            break;
+          case PROCESSOR_ARCHITECTURE_INTEL:
+            strcpy (buf->machine, "i386");
+            if (info.wProcessorLevel >= 3)
+              buf->machine[1] =
+                '0' + (info.wProcessorLevel <= 6 ? info.wProcessorLevel : 6);
+            break;
+          case PROCESSOR_ARCHITECTURE_IA32_ON_WIN64:
+            strcpy (buf->machine, "i686");
+            break;
+          case PROCESSOR_ARCHITECTURE_MIPS:
+            strcpy (buf->machine, "mips");
+            break;
+          case PROCESSOR_ARCHITECTURE_ALPHA:
+          case PROCESSOR_ARCHITECTURE_ALPHA64:
+            strcpy (buf->machine, "alpha");
+            break;
+          case PROCESSOR_ARCHITECTURE_PPC:
+            strcpy (buf->machine, "powerpc");
+            break;
+          case PROCESSOR_ARCHITECTURE_SHX:
+            strcpy (buf->machine, "sh");
+            break;
+          case PROCESSOR_ARCHITECTURE_ARM:
+            strcpy (buf->machine, "arm");
+            break;
+          default:
+            strcpy (buf->machine, "unknown");
+            break;
+          }
+      }
+    else
+      {
+        /* Windows 95/98/ME.  */
+        switch (info.dwProcessorType)
+          {
+          case PROCESSOR_AMD_X8664:
+            strcpy (buf->machine, "x86_64");
+            break;
+          case PROCESSOR_INTEL_IA64:
+            strcpy (buf->machine, "ia64");
+            break;
+          default:
+            if (info.dwProcessorType % 100 == 86)
+              sprintf (buf->machine, "i%u",
+                       (unsigned int) info.dwProcessorType);
+            else
+              strcpy (buf->machine, "unknown");
+            break;
+          }
+      }
+  }
+
+  return 0;
+}
+
+#endif
+
+#if !defined(HAVE_WARN)
+void
+warn(const char *fmt, ...)
+{
+        va_list ap;
+
+        va_start(ap, fmt);
+        vwarn(fmt, ap);
+        va_end(ap);
+}
+#endif
+
+#if !defined(HAVE_WARNX)
+void
+warnx(const char *fmt, ...)
+{
+        va_list ap;
+
+        va_start(ap, fmt);
         vwarnx(fmt, ap);
@@ -622 +2959,618 @@ warnx(const char *fmt, ...)
 #endif
+
+#if !defined(HAVE_WAIT)
+/* Specification.  */
+#include "wait.h"
+pid_t
+wait (int *statusp)
+{
+    return waitpid((pid_t) -1, statusp, WUNTRACED);
+}
+#endif
+
+#if !defined(HAVE_WAITPID)
+/* Wait for process state change.
+   Copyright (C) 2001-2003, 2005-2018 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.
+
+   You should have received a copy of the GNU General Public License
+   along with this program; if not, see <https://www.gnu.org/licenses/>.  */
+
+/* Specification.  */
+#include "wait.h"
+
+/* Implementation for native Windows systems.  */
+
+#include <process.h> /* for _cwait, WAIT_CHILD */
+
+pid_t
+waitpid (pid_t pid, int *statusp, int options)
+{
+    return _cwait (statusp, pid, WAIT_CHILD);
+}
+#endif
+
+#if (defined _WIN32 && ! defined __CYGWIN__)
+char *
+getShellLaunchPrefix()
+{
+    const char *sysRootPath = getenv("SYSROOTWINDOWSPATH");
+    const char *msystemPrefix = getenv("MSYSTEM");
+
+    if (sysRootPath == NULL || msystemPrefix == NULL) {
+        return NULL; /*we can't find mingw shell installed on this system */
+    }
+    else {
+        /* we will return something like
+         * C:\msys64\usr\bin\env MSYSTEM=MINGW64 /usr/bin/bash -lc
+         */
+        return str_concat(
+                   str_concat(
+                       str_concat(sysRootPath, "usr\\bin\\env.exe MSYSTEM=", 0),
+                       msystemPrefix, 0),
+                   "/usr/bin/bash -lc", STR_ADDSPACE);
+    }
+}
+
+char * getUnixPathCmd(const char *path)
+{
+    return str_concat(
+            "cygpath -u", str_concat("\"",
+                            str_concat(path, "\"", 0),
+                            0),
+                            STR_ADDSPACE);
+}
+
+#endif
+
+#include <stdint.h>
+#include <stdlib.h>
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include "headers-mingw/stdlib.h"
+#endif
+#include <string.h>
+
+size_t str_escape(char *dst, const char *src, size_t dstLen)
+{
+    const char complexCharMap[] = "abtnvfr";
+
+    size_t i;
+    size_t srcLen = strlen(src);
+    size_t dstIdx = 0;
+
+    // If caller wants to determine required length (supplying NULL for dst)
+    // then we set dstLen to SIZE_MAX and pretend the buffer is the largest
+    // possible, but we never write to it. Caller can also provide dstLen
+    // as 0 if no limit is wanted.
+    if (dst == NULL || dstLen == 0) dstLen = SIZE_MAX;
+
+    for (i = 0; i < srcLen && dstIdx < dstLen; i++)
+    {
+        size_t complexIdx = 0;
+
+        switch (src[i])
+        {
+            case '\'':
+            case '\"':
+            case '\\':
+                if (dst && dstIdx <= dstLen - 2)
+                {
+                    dst[dstIdx++] = '\\';
+                    dst[dstIdx++] = src[i];
+                }
+                else dstIdx += 2;
+                break;
+
+            case '\r': complexIdx++;
+            case '\f': complexIdx++;
+            case '\v': complexIdx++;
+            case '\n': complexIdx++;
+            case '\t': complexIdx++;
+            case '\b': complexIdx++;
+            case '\a':
+                if (dst && dstIdx <= dstLen - 2)
+                {
+                    dst[dstIdx++] = '\\';
+                    dst[dstIdx++] = complexCharMap[complexIdx];
+                }
+                else dstIdx += 2;
+                break;
+
+            default:
+                if (isprint(src[i]))
+                {
+                    // simply copy the character
+                    if (dst)
+                        dst[dstIdx++] = src[i];
+                    else
+                        dstIdx++;
+                }
+                else
+                {
+                    // produce octal escape sequence
+                    if (dst && dstIdx <= dstLen - 4)
+                    {
+                        dst[dstIdx++] = '\\';
+                        dst[dstIdx++] = ((src[i] & 0300) >> 6) + '0';
+                        dst[dstIdx++] = ((src[i] & 0070) >> 3) + '0';
+                        dst[dstIdx++] = ((src[i] & 0007) >> 0) + '0';
+                    }
+                    else
+                    {
+                        dstIdx += 4;
+                    }
+                }
+        }
+    }
+
+    if (dst && dstIdx <= dstLen)
+        dst[dstIdx] = '\0';
+
+    return dstIdx;
+}
+
+size_t str_escape_dblquote(char *dst, const char *src, size_t dstLen)
+{
+
+    size_t i;
+    size_t srcLen = strlen(src);
+    size_t dstIdx = 0;
+
+    // If caller wants to determine required length (supplying NULL for dst)
+    // then we set dstLen to SIZE_MAX and pretend the buffer is the largest
+    // possible, but we never write to it. Caller can also provide dstLen
+    // as 0 if no limit is wanted.
+    if (dst == NULL || dstLen == 0) dstLen = SIZE_MAX;
+
+    for (i = 0; i < srcLen && dstIdx < dstLen; i++)
+    {
+        size_t complexIdx = 0;
+
+        switch (src[i])
+        {
+            case '\"':
+                if (dst && dstIdx <= dstLen - 2)
+                {
+                    dst[dstIdx++] = '\\';
+                    dst[dstIdx++] = src[i];
+                }
+                else dstIdx += 2;
+                break;
+            case '\\':
+                if (dst && dstIdx <= dstLen - 2)
+                {
+                    dst[dstIdx++] = '\\';
+                    dst[dstIdx++] = src[i];
+                }
+                else dstIdx += 2;
+                break;
+            default:
+//                if (isprint(src[i]) || src[i] == '\n' || src[i] == '\r')
+//                {
+                    // simply copy the character
+                    if (dst)
+                        dst[dstIdx++] = src[i];
+                    else
+                        dstIdx++;
+//                }
+//                else {
+//                    dst[dstIdx++] = ' ';
+//                }
+        }
+    }
+
+    if (dst && dstIdx <= dstLen)
+        dst[dstIdx] = '\0';
+
+    return dstIdx;
+}
+
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include <windows.h>
+//#include <stdio.h>
+//#include <malloc.h>
+
+#define bool        _Bool
+#define true        1
+#define false        0
+
+#define null ((void*)0)
+
+typedef struct system_np_s {
+    HANDLE child_stdout_read;
+    HANDLE child_stderr_read;
+    HANDLE reader;
+    PROCESS_INFORMATION pi;
+    const char* command;
+    char* stdout_data;
+    int   stdout_data_size;
+    char* stderr_data;
+    int   stderr_data_size;
+    int*  exit_code;
+    int   timeout; // timeout in milliseconds or -1 for INIFINTE
+} system_np_t;
+
+static int peek_pipe(HANDLE pipe, char* data, int size) {
+    char buffer[4 * 1024];
+    DWORD read = 0;
+    DWORD available = 0;
+    bool b = PeekNamedPipe(pipe, null, sizeof(buffer), null, &available, null);
+    if (!b) {
+        return -1;
+    } else if (available > 0) {
+        int bytes = min(sizeof(buffer), available);
+        b = ReadFile(pipe, buffer, bytes, &read, null);
+        if (!b) {
+            return -1;
+        }
+        if (data != null && size > 0) {
+            int n = min(size - 1, (int)read);
+            memcpy(data, buffer, n);
+            data[n + 1] = 0; // always zero terminated
+            return n;
+        }
+    }
+    return 0;
+}
+
+static DWORD WINAPI read_from_all_pipes_fully(void* p) {
+    system_np_t* system = (system_np_t*)p;
+    unsigned long long milliseconds = GetTickCount64(); // since boot time
+    char* out = system->stdout_data != null && system->stdout_data_size > 0 ? system->stdout_data : null;
+    char* err = system->stderr_data != null && system->stderr_data_size > 0 ? system->stderr_data : null;
+    int out_bytes = system->stdout_data != null && system->stdout_data_size > 0 ? system->stdout_data_size - 1 : 0;
+    int err_bytes = system->stderr_data != null && system->stderr_data_size > 0 ? system->stderr_data_size - 1 : 0;
+    for (;;) {
+        int read_stdout = peek_pipe(system->child_stdout_read, out, out_bytes);
+        if (read_stdout > 0 && out != null) { out += read_stdout; out_bytes -= read_stdout; }
+        int read_stderr = peek_pipe(system->child_stderr_read, err, err_bytes);
+        if (read_stderr > 0 && err != null) { err += read_stderr; err_bytes -= read_stderr; }
+        if (read_stdout < 0 && read_stderr < 0) { break; } // both pipes are closed
+        unsigned long long time_spent_in_milliseconds = GetTickCount64() - milliseconds;
+        if (system->timeout > 0 && time_spent_in_milliseconds > system->timeout) { break; }
+        if (read_stdout == 0 && read_stderr == 0) { // nothing has been read from both pipes
+            HANDLE handles[2] = {system->child_stdout_read, system->child_stderr_read};
+            WaitForMultipleObjects(2, handles, false, 1); // wait for at least 1 millisecond (more likely 16)
+        }
+    }
+    if (out != null) { *out = 0; }
+    if (err != null) { *err = 0; }
+    return 0;
+}
+
+static int create_child_process(system_np_t* system) {
+    SECURITY_ATTRIBUTES sa = {0};
+    sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+    sa.bInheritHandle = true;
+    sa.lpSecurityDescriptor = null;
+    HANDLE child_stdout_write = INVALID_HANDLE_VALUE;
+    HANDLE child_stderr_write = INVALID_HANDLE_VALUE;
+    if (!CreatePipe(&system->child_stderr_read, &child_stderr_write, &sa, 0) ) {
+        return GetLastError();
+    }
+    if (!SetHandleInformation(system->child_stderr_read, HANDLE_FLAG_INHERIT, 0) ){
+        return GetLastError();
+    }
+    if (!CreatePipe(&system->child_stdout_read, &child_stdout_write, &sa, 0) ) {
+        return GetLastError();
+    }
+    if (!SetHandleInformation(system->child_stdout_read, HANDLE_FLAG_INHERIT, 0) ){
+        return GetLastError();
+    }
+    // Set the text I want to run
+    STARTUPINFO siStartInfo = {0};
+    siStartInfo.cb = sizeof(STARTUPINFO);
+    siStartInfo.hStdError = child_stderr_write;
+    siStartInfo.hStdOutput = child_stdout_write;
+    siStartInfo.dwFlags |= STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW;
+    siStartInfo.wShowWindow = SW_HIDE;
+    bool b = CreateProcessA(null,
+                            (char*)system->command,
+                            null,               // process security attributes
+                            null,               // primary thread security attributes
+                            true,               // handles are inherited
+                            CREATE_NO_WINDOW,   // creation flags
+                            null,               // use parent's environment
+                            null,               // use parent's current directory
+                            &siStartInfo,       // STARTUPINFO pointer
+                            &system->pi);       // receives PROCESS_INFORMATION
+    int err = GetLastError();
+    CloseHandle(child_stderr_write);
+    CloseHandle(child_stdout_write);
+    if (!b) {
+        CloseHandle(system->child_stdout_read); system->child_stdout_read = INVALID_HANDLE_VALUE;
+        CloseHandle(system->child_stderr_read); system->child_stderr_read = INVALID_HANDLE_VALUE;
+    }
+    return b ? 0 : err;
+}
+
+int system_np(const char* command, int timeout_milliseconds,
+              char* stdout_data, int stdout_data_size,
+              char* stderr_data, int stderr_data_size, int* exit_code) {
+    system_np_t system = {0};
+    if (exit_code != null) { *exit_code = 0; }
+    if (stdout_data != null && stdout_data_size > 0) { stdout_data[0] = 0; }
+    if (stderr_data != null && stderr_data_size > 0) { stderr_data[0] = 0; }
+    system.timeout = timeout_milliseconds > 0 ? timeout_milliseconds : -1;
+    system.command = command;
+    system.stdout_data = stdout_data;
+    system.stderr_data = stderr_data;
+    system.stdout_data_size = stdout_data_size;
+    system.stderr_data_size = stderr_data_size;
+    int r = create_child_process(&system);
+    if (r == 0) {
+        system.reader = CreateThread(null, 0, read_from_all_pipes_fully, &system, 0, null);
+        if (system.reader == null) { // in theory should rarely happen only when system super low on resources
+            r = GetLastError();
+            TerminateProcess(system.pi.hProcess, ECANCELED);
+        } else {
+            bool thread_done  = WaitForSingleObject(system.pi.hThread, timeout_milliseconds) == 0;
+            bool process_done = WaitForSingleObject(system.pi.hProcess, timeout_milliseconds) == 0;
+            if (!thread_done || !process_done) {
+                TerminateProcess(system.pi.hProcess, ETIME);
+            }
+            if (exit_code != null) {
+                GetExitCodeProcess(system.pi.hProcess, (DWORD*)exit_code);
+            }
+            CloseHandle(system.pi.hThread);
+            CloseHandle(system.pi.hProcess);
+            CloseHandle(system.child_stdout_read); system.child_stdout_read = INVALID_HANDLE_VALUE;
+            CloseHandle(system.child_stderr_read); system.child_stderr_read = INVALID_HANDLE_VALUE;
+            WaitForSingleObject(system.reader, INFINITE); // join thread
+            CloseHandle(system.reader);
+        }
+    }
+    if (stdout_data != null && stdout_data_size > 0) { stdout_data[stdout_data_size - 1] = 0; }
+    if (stderr_data != null && stderr_data_size > 0) { stderr_data[stderr_data_size - 1] = 0; }
+    return r;
+}
+#endif
+
+#ifndef NO_REGEX
+#if (!defined(HAVE_REGCOMP) || !defined(HAVE_REGERROR) || !defined(HAVE_REGEXEC) || !defined(HAVE_REGFREE))
+
+#if (defined _WIN32 && ! defined __CYGWIN__)
+#include <windows.h>
+#endif
+/* Return the codeset of the current locale, if this is easily deducible.
+   Otherwise, return "".  */
+static char *
+ctype_codeset(void) {
+    static char buf[2 + 10 + 1];
+    char const *locale = setlocale(LC_CTYPE, NULL);
+    char *codeset = buf;
+    size_t codesetlen;
+    codeset[0] = '\0';
+
+    if (locale && locale[0]) {
+        /* If the locale name contains an encoding after the dot, return it.  */
+        char *dot = strchr(locale, '.');
+
+        if (dot) {
+            /* Look for the possible @... trailer and remove it, if any.  */
+            char *codeset_start = dot + 1;
+            char const *modifier = strchr(codeset_start, '@');
+
+            if (!modifier)
+                codeset = codeset_start;
+            else {
+                codesetlen = modifier - codeset_start;
+                if (codesetlen < sizeof buf) {
+                    codeset = memcpy(buf, codeset_start, codesetlen);
+                    codeset[codesetlen] = '\0';
+                }
+            }
+        }
+    }
+
+    /* If setlocale is successful, it returns the number of the
+     codepage, as a string.  Otherwise, fall back on Windows API
+     GetACP, which returns the locale's codepage as a number (although
+     this doesn't change according to what the 'setlocale' call specified).
+     Either way, prepend "CP" to make it a valid codeset name.  */
+    codesetlen = strlen(codeset);
+    if (0 < codesetlen && codesetlen < sizeof buf - 2)
+        memmove(buf + 2, codeset, codesetlen + 1);
+    else
+        sprintf(buf + 2, "%u", GetACP());
+    codeset = memcpy(buf, "CP", 2);
+    return codeset;
+}
+
+/* Provide nl_langinfo from scratch, either for native MS-Windows, or
+   for old Unix platforms without locales, such as Linux libc5 or
+   BeOS.  */
+
+# include <time.h>
+
+char *
+nl_langinfo(nl_item item) {
+    static char nlbuf[100];
+    struct tm tmm = {0};
+
+    switch (item) {
+        /* nl_langinfo items of the LC_CTYPE category */
+        case CODESET: {
+            char *codeset = ctype_codeset();
+            if (*codeset)
+                return codeset;
+        }
+            return (char *) "ISO-8859-1";
+            /* nl_langinfo items of the LC_NUMERIC category */
+        case RADIXCHAR:
+            return localeconv()->decimal_point;
+        case THOUSEP:
+            return localeconv()->thousands_sep;
+            /* nl_langinfo items of the LC_TIME category.
+               TODO: Really use the locale.  */
+        case D_T_FMT:
+        case ERA_D_T_FMT:
+            return (char *) "%a %b %e %H:%M:%S %Y";
+        case D_FMT:
+        case ERA_D_FMT:
+            return (char *) "%m/%d/%y";
+        case T_FMT:
+        case ERA_T_FMT:
+            return (char *) "%H:%M:%S";
+        case T_FMT_AMPM:
+            return (char *) "%I:%M:%S %p";
+        case AM_STR:
+            if (!strftime(nlbuf, sizeof nlbuf, "%p", &tmm))
+                return (char *) "AM";
+            return nlbuf;
+        case PM_STR:
+            tmm.tm_hour = 12;
+            if (!strftime(nlbuf, sizeof nlbuf, "%p", &tmm))
+                return (char *) "PM";
+            return nlbuf;
+        case DAY_1:
+        case DAY_2:
+        case DAY_3:
+        case DAY_4:
+        case DAY_5:
+        case DAY_6:
+        case DAY_7: {
+            static char const days[][sizeof "Wednesday"] = {
+                    "Sunday", "Monday", "Tuesday", "Wednesday", "Thursday",
+                    "Friday", "Saturday"
+            };
+            tmm.tm_wday = item - DAY_1;
+            if (!strftime(nlbuf, sizeof nlbuf, "%A", &tmm))
+                return (char *) days[item - DAY_1];
+            return nlbuf;
+        }
+        case ABDAY_1:
+        case ABDAY_2:
+        case ABDAY_3:
+        case ABDAY_4:
+        case ABDAY_5:
+        case ABDAY_6:
+        case ABDAY_7: {
+            static char const abdays[][sizeof "Sun"] = {
+                    "Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"
+            };
+            tmm.tm_wday = item - ABDAY_1;
+            if (!strftime(nlbuf, sizeof nlbuf, "%a", &tmm))
+                return (char *) abdays[item - ABDAY_1];
+            return nlbuf;
+        }
+            {
+                static char const months[][sizeof "September"] = {
+                        "January", "February", "March", "April", "May", "June", "July",
+                        "September", "October", "November", "December"
+                };
+                case MON_1:
+                case MON_2:
+                case MON_3:
+                case MON_4:
+                case MON_5:
+                case MON_6:
+                case MON_7:
+                case MON_8:
+                case MON_9:
+                case MON_10:
+                case MON_11:
+                case MON_12:
+                    tmm.tm_mon = item - MON_1;
+                if (!strftime(nlbuf, sizeof nlbuf, "%B", &tmm))
+                    return (char *) months[item - MON_1];
+                return nlbuf;
+                case ALTMON_1:
+                case ALTMON_2:
+                case ALTMON_3:
+                case ALTMON_4:
+                case ALTMON_5:
+                case ALTMON_6:
+                case ALTMON_7:
+                case ALTMON_8:
+                case ALTMON_9:
+                case ALTMON_10:
+                case ALTMON_11:
+                case ALTMON_12:
+                    tmm.tm_mon = item - ALTMON_1;
+                /* The platforms without nl_langinfo() don't support strftime with %OB.
+                   We don't even need to try.  */
+                if (!strftime(nlbuf, sizeof nlbuf, "%B", &tmm))
+                    return (char *) months[item - ALTMON_1];
+                return nlbuf;
+            }
+        case ABMON_1:
+        case ABMON_2:
+        case ABMON_3:
+        case ABMON_4:
+        case ABMON_5:
+        case ABMON_6:
+        case ABMON_7:
+        case ABMON_8:
+        case ABMON_9:
+        case ABMON_10:
+        case ABMON_11:
+        case ABMON_12: {
+            static char const abmonths[][sizeof "Jan"] = {
+                    "Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul",
+                    "Sep", "Oct", "Nov", "Dec"
+            };
+            tmm.tm_mon = item - ABMON_1;
+            if (!strftime(nlbuf, sizeof nlbuf, "%b", &tmm))
+                return (char *) abmonths[item - ABMON_1];
+            return nlbuf;
+        }
+        case ERA:
+            return (char *) "";
+        case ALT_DIGITS:
+            return (char *) "\0\0\0\0\0\0\0\0\0\0";
+            /* nl_langinfo items of the LC_MONETARY category.  */
+        case CRNCYSTR:
+            return localeconv()->currency_symbol;
+# ifdef INT_CURR_SYMBOL
+            case INT_CURR_SYMBOL:
+      return localeconv () ->int_curr_symbol;
+    case MON_DECIMAL_POINT:
+      return localeconv () ->mon_decimal_point;
+    case MON_THOUSANDS_SEP:
+      return localeconv () ->mon_thousands_sep;
+    case MON_GROUPING:
+      return localeconv () ->mon_grouping;
+    case POSITIVE_SIGN:
+      return localeconv () ->positive_sign;
+    case NEGATIVE_SIGN:
+      return localeconv () ->negative_sign;
+    case FRAC_DIGITS:
+      return & localeconv () ->frac_digits;
+    case INT_FRAC_DIGITS:
+      return & localeconv () ->int_frac_digits;
+    case P_CS_PRECEDES:
+      return & localeconv () ->p_cs_precedes;
+    case N_CS_PRECEDES:
+      return & localeconv () ->n_cs_precedes;
+    case P_SEP_BY_SPACE:
+      return & localeconv () ->p_sep_by_space;
+    case N_SEP_BY_SPACE:
+      return & localeconv () ->n_sep_by_space;
+    case P_SIGN_POSN:
+      return & localeconv () ->p_sign_posn;
+    case N_SIGN_POSN:
+      return & localeconv () ->n_sign_posn;
+# endif
+            /* nl_langinfo items of the LC_MESSAGES category
+               TODO: Really use the locale. */
+        case YESEXPR:
+            return (char *) "^[yY]";
+        case NOEXPR:
+            return (char *) "^[nN]";
+        default:
+            return (char *) "";
+    }
+}
+
+#endif
+#endif
\ No newline at end of file
diff --git a/var.c b/var.c
index 6f8d4c3..5e4e9d2 100644
--- a/var.c
+++ b/var.c
@@ -73,3 +73,3 @@ static char rcsid[] = "$NetBSD: var.c,v 1.221 2018/12/21 05:50:19 sjg Exp $";
 #else
-#include <sys/cdefs.h>
+                                                                                                                        #include <sys/cdefs.h>
 #ifndef lint
@@ -126,6 +126,20 @@ __RCSID("$NetBSD: var.c,v 1.221 2018/12/21 05:50:19 sjg Exp $");
 #include    <sys/stat.h>
+
+#if (defined _WIN32 && !defined __CYGWIN__)
+#include "headers-mingw/sys_stat.h"
+#endif
 #ifndef NO_REGEX
+
 #include    <sys/types.h>
+
+# if (defined _WIN32 && !defined __CYGWIN__)
+                                                                                                                        #include "headers-mingw/regex.h"
+#include "headers-mingw/regex_internal.h"
+# else
+
 #include    <regex.h>
+
+# endif
 #endif
+
 #include    <ctype.h>
@@ -153,3 +167,3 @@ char **savedEnv = NULL;
  */
-char 	var_Error[] = "";
+char var_Error[] = "";

@@ -160,3 +174,3 @@ char 	var_Error[] = "";
  */
-static char	varNoError[] = "";
+static char varNoError[] = "";

@@ -188,18 +202,18 @@ static Boolean save_dollars = FALSE;
  */
-GNode          *VAR_INTERNAL; /* variables from make itself */
-GNode          *VAR_GLOBAL;   /* variables from the makefile */
-GNode          *VAR_CMD;      /* variables defined on the command-line */
+GNode *VAR_INTERNAL; /* variables from make itself */
+GNode *VAR_GLOBAL;   /* variables from the makefile */
+GNode *VAR_CMD;      /* variables defined on the command-line */

-#define FIND_CMD	0x1   /* look in VAR_CMD when searching */
-#define FIND_GLOBAL	0x2   /* look in VAR_GLOBAL as well */
-#define FIND_ENV  	0x4   /* look in the environment also */
+#define FIND_CMD    0x1   /* look in VAR_CMD when searching */
+#define FIND_GLOBAL    0x2   /* look in VAR_GLOBAL as well */
+#define FIND_ENV    0x4   /* look in the environment also */

 typedef struct Var {
-    char          *name;	/* the variable's name */
-    Buffer	  val;		/* its value */
-    int		  flags;    	/* miscellaneous status flags */
-#define VAR_IN_USE	1   	    /* Variable's value currently being used.
+    char *name;    /* the variable's name */
+    Buffer val;        /* its value */
+    int flags;        /* miscellaneous status flags */
+#define VAR_IN_USE    1        /* Variable's value currently being used.
 				     * Used to avoid recursion */
-#define VAR_FROM_ENV	2   	    /* Variable comes from the environment */
-#define VAR_JUNK  	4   	    /* Variable is a junk variable that
+#define VAR_FROM_ENV    2        /* Variable comes from the environment */
+#define VAR_JUNK    4        /* Variable is a junk variable that
 				     * should be destroyed when done with
@@ -207,11 +221,11 @@ typedef struct Var {
 				     * modified variables */
-#define VAR_KEEP	8	    /* Variable is VAR_JUNK, but we found
+#define VAR_KEEP    8        /* Variable is VAR_JUNK, but we found
 				     * a use for it in some modifier and
 				     * the value is therefore valid */
-#define VAR_EXPORTED	16 	    /* Variable is exported */
-#define VAR_REEXPORT	32	    /* Indicate if var needs re-export.
+#define VAR_EXPORTED    16        /* Variable is exported */
+#define VAR_REEXPORT    32        /* Indicate if var needs re-export.
 				     * This would be true if it contains $'s
 				     */
-#define VAR_FROM_CMD	64 	    /* Variable came from command line */
-}  Var;
+#define VAR_FROM_CMD    64        /* Variable came from command line */
+} Var;

@@ -220,5 +234,5 @@ typedef struct Var {
  */
-#define VAR_EXPORTED_NONE	0
-#define VAR_EXPORTED_YES	1
-#define VAR_EXPORTED_ALL	2
+#define VAR_EXPORTED_NONE    0
+#define VAR_EXPORTED_YES    1
+#define VAR_EXPORTED_ALL    2
 static int var_exportedVars = VAR_EXPORTED_NONE;
@@ -228,3 +242,3 @@ static int var_exportedVars = VAR_EXPORTED_NONE;
  */
-#define VAR_EXPORT_PARENT	1
+#define VAR_EXPORT_PARENT    1
 /*
@@ -232,14 +246,14 @@ static int var_exportedVars = VAR_EXPORTED_NONE;
  */
-#define VAR_EXPORT_LITERAL	2
+#define VAR_EXPORT_LITERAL    2

 /* Var*Pattern flags */
-#define VAR_SUB_GLOBAL	0x01	/* Apply substitution globally */
-#define VAR_SUB_ONE	0x02	/* Apply substitution to one word */
-#define VAR_SUB_MATCHED	0x04	/* There was a match */
-#define VAR_MATCH_START	0x08	/* Match at start of word */
-#define VAR_MATCH_END	0x10	/* Match at end of word */
-#define VAR_NOSUBST	0x20	/* don't expand vars in VarGetPattern */
+#define VAR_SUB_GLOBAL    0x01    /* Apply substitution globally */
+#define VAR_SUB_ONE    0x02    /* Apply substitution to one word */
+#define VAR_SUB_MATCHED    0x04    /* There was a match */
+#define VAR_MATCH_START    0x08    /* Match at start of word */
+#define VAR_MATCH_END    0x10    /* Match at end of word */
+#define VAR_NOSUBST    0x20    /* don't expand vars in VarGetPattern */

 /* Var_Set flags */
-#define VAR_NO_EXPORT	0x01	/* do not export */
+#define VAR_NO_EXPORT    0x01    /* do not export */

@@ -251,4 +265,4 @@ typedef struct {
      */
-    Byte	varSpace;	/* Word separator in expansions */
-    Boolean	oneBigWord;	/* TRUE if we will treat the variable as a
+    Byte varSpace;    /* Word separator in expansions */
+    Boolean oneBigWord;    /* TRUE if we will treat the variable as a
 				 * single big word, even if it contains
@@ -262,7 +276,7 @@ typedef struct {
 typedef struct {
-    const char   *lhs;	    /* String to match */
-    int		  leftLen; /* Length of string */
-    const char   *rhs;	    /* Replacement string (w/ &'s removed) */
-    int		  rightLen; /* Length of replacement */
-    int		  flags;
+    const char *lhs;        /* String to match */
+    int leftLen; /* Length of string */
+    const char *rhs;        /* Replacement string (w/ &'s removed) */
+    int rightLen; /* Length of replacement */
+    int flags;
 } VarPattern;
@@ -271,8 +285,8 @@ typedef struct {
 typedef struct {
-    GNode	*ctxt;		/* variable context */
-    char	*tvar;		/* name of temp var */
-    int		tvarLen;
-    char	*str;		/* string to expand */
-    int		strLen;
-    int		errnum;		/* errnum for not defined */
+    GNode *ctxt;        /* variable context */
+    char *tvar;        /* name of temp var */
+    int tvarLen;
+    char *str;        /* string to expand */
+    int strLen;
+    int errnum;        /* errnum for not defined */
 } VarLoop_t;
@@ -282,7 +296,7 @@ typedef struct {
 typedef struct {
-    regex_t	   re;
-    int		   nsub;
-    regmatch_t 	  *matches;
-    char 	  *replace;
-    int		   flags;
+    regex_t re;
+    int nsub;
+    regmatch_t *matches;
+    char *replace;
+    int flags;
 } VarREPattern;
@@ -292,4 +306,4 @@ typedef struct {
 typedef struct {
-    int		start;		/* first word to select */
-    int		end;		/* last word to select */
+    int start;        /* first word to select */
+    int end;        /* last word to select */
 } VarSelectWords_t;
@@ -297,46 +311,70 @@ typedef struct {
 static Var *VarFind(const char *, GNode *, int);
+
 static void VarAdd(const char *, const char *, GNode *);
+
 static Boolean VarHead(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                       char *, Boolean, Buffer *, void *);
+
 static Boolean VarTail(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                       char *, Boolean, Buffer *, void *);
+
 static Boolean VarSuffix(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                         char *, Boolean, Buffer *, void *);
+
 static Boolean VarRoot(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                       char *, Boolean, Buffer *, void *);
+
 static Boolean VarMatch(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                        char *, Boolean, Buffer *, void *);
+
 #ifdef SYSVVARSUB
+
 static Boolean VarSYSVMatch(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                            char *, Boolean, Buffer *, void *);
+
 #endif
+
 static Boolean VarNoMatch(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                          char *, Boolean, Buffer *, void *);
+
 #ifndef NO_REGEX
+
 static void VarREError(int, regex_t *, const char *);
+
 static Boolean VarRESubstitute(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                               char *, Boolean, Buffer *, void *);
+
 #endif
+
 static Boolean VarSubstitute(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                             char *, Boolean, Buffer *, void *);
+
 static Boolean VarLoopExpand(GNode *, Var_Parse_State *,
-			char *, Boolean, Buffer *, void *);
+                             char *, Boolean, Buffer *, void *);
+
 static char *VarGetPattern(GNode *, Var_Parse_State *,
-			   int, const char **, int, int *, int *,
-			   VarPattern *);
+                           int, const char **, int, int *, int *,
+                           VarPattern *);
+
 static char *VarQuote(char *, Boolean);
+
 static char *VarHash(char *);
+
 static char *VarModify(GNode *, Var_Parse_State *,
-    const char *,
-    Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer *, void *),
-    void *);
+                       const char *,
+                       Boolean (*)(GNode *, Var_Parse_State *, char *, Boolean, Buffer *, void *),
+                       void *);
+
 static char *VarOrder(const char *, const char);
+
 static char *VarUniq(const char *);
+
 static int VarWordCompare(const void *, const void *);
+
 static void VarPrintVar(void *);

-#define BROPEN	'{'
-#define BRCLOSE	'}'
-#define PROPEN	'('
-#define PRCLOSE	')'
+#define BROPEN    '{'
+#define BRCLOSE    '}'
+#define PROPEN    '('
+#define PRCLOSE    ')'

@@ -365,8 +403,7 @@ static void VarPrintVar(void *);
 static Var *
-VarFind(const char *name, GNode *ctxt, int flags)
-{
-    Hash_Entry         	*var;
-    Var			*v;
+VarFind(const char *name, GNode *ctxt, int flags) {
+    Hash_Entry *var;
+    Var *v;

-	/*
+    /*
 	 * If the variable name begins with a '.', it could very well be one of
@@ -376,33 +413,33 @@ VarFind(const char *name, GNode *ctxt, int flags)
 	 */
-	if (*name == '.' && isupper((unsigned char) name[1]))
-		switch (name[1]) {
-		case 'A':
-			if (!strcmp(name, ".ALLSRC"))
-				name = ALLSRC;
-			if (!strcmp(name, ".ARCHIVE"))
-				name = ARCHIVE;
-			break;
-		case 'I':
-			if (!strcmp(name, ".IMPSRC"))
-				name = IMPSRC;
-			break;
-		case 'M':
-			if (!strcmp(name, ".MEMBER"))
-				name = MEMBER;
-			break;
-		case 'O':
-			if (!strcmp(name, ".OODATE"))
-				name = OODATE;
-			break;
-		case 'P':
-			if (!strcmp(name, ".PREFIX"))
-				name = PREFIX;
-			break;
-		case 'T':
-			if (!strcmp(name, ".TARGET"))
-				name = TARGET;
-			break;
-		}
+    if (*name == '.' && isupper((unsigned char) name[1]))
+        switch (name[1]) {
+            case 'A':
+                if (!strcmp(name, ".ALLSRC"))
+                    name = ALLSRC;
+                if (!strcmp(name, ".ARCHIVE"))
+                    name = ARCHIVE;
+                break;
+            case 'I':
+                if (!strcmp(name, ".IMPSRC"))
+                    name = IMPSRC;
+                break;
+            case 'M':
+                if (!strcmp(name, ".MEMBER"))
+                    name = MEMBER;
+                break;
+            case 'O':
+                if (!strcmp(name, ".OODATE"))
+                    name = OODATE;
+                break;
+            case 'P':
+                if (!strcmp(name, ".PREFIX"))
+                    name = PREFIX;
+                break;
+            case 'T':
+                if (!strcmp(name, ".TARGET"))
+                    name = TARGET;
+                break;
+        }
 #ifdef notyet
-    /* for compatibility with gmake */
+                                                                                                                            /* for compatibility with gmake */
     if (name[0] == '^' && name[1] == '\0')
@@ -419,48 +456,46 @@ VarFind(const char *name, GNode *ctxt, int flags)
     if ((var == NULL) && (flags & FIND_CMD) && (ctxt != VAR_CMD)) {
-	var = Hash_FindEntry(&VAR_CMD->context, name);
+        var = Hash_FindEntry(&VAR_CMD->context, name);
     }
     if (!checkEnvFirst && (var == NULL) && (flags & FIND_GLOBAL) &&
-	(ctxt != VAR_GLOBAL))
-    {
-	var = Hash_FindEntry(&VAR_GLOBAL->context, name);
-	if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
-	    /* VAR_INTERNAL is subordinate to VAR_GLOBAL */
-	    var = Hash_FindEntry(&VAR_INTERNAL->context, name);
-	}
+        (ctxt != VAR_GLOBAL)) {
+        var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+        if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
+            /* VAR_INTERNAL is subordinate to VAR_GLOBAL */
+            var = Hash_FindEntry(&VAR_INTERNAL->context, name);
+        }
     }
     if ((var == NULL) && (flags & FIND_ENV)) {
-	char *env;
-
-	if ((env = getenv(name)) != NULL) {
-	    int		len;
-
-	    v = bmake_malloc(sizeof(Var));
-	    v->name = bmake_strdup(name);
-
-	    len = strlen(env);
-
-	    Buf_Init(&v->val, len + 1);
-	    Buf_AddBytes(&v->val, len, env);
-
-	    v->flags = VAR_FROM_ENV;
-	    return (v);
-	} else if (checkEnvFirst && (flags & FIND_GLOBAL) &&
-		   (ctxt != VAR_GLOBAL))
-	{
-	    var = Hash_FindEntry(&VAR_GLOBAL->context, name);
-	    if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
-		var = Hash_FindEntry(&VAR_INTERNAL->context, name);
-	    }
-	    if (var == NULL) {
-		return NULL;
-	    } else {
-		return ((Var *)Hash_GetValue(var));
-	    }
-	} else {
-	    return NULL;
-	}
+        char *env;
+
+        if ((env = getenv(name)) != NULL) {
+            int len;
+
+            v = bmake_malloc(sizeof(Var));
+            v->name = bmake_strdup(name);
+
+            len = strlen(env);
+
+            Buf_Init(&v->val, len + 1);
+            Buf_AddBytes(&v->val, len, env);
+
+            v->flags = VAR_FROM_ENV;
+            return (v);
+        } else if (checkEnvFirst && (flags & FIND_GLOBAL) &&
+                   (ctxt != VAR_GLOBAL)) {
+            var = Hash_FindEntry(&VAR_GLOBAL->context, name);
+            if ((var == NULL) && (ctxt != VAR_INTERNAL)) {
+                var = Hash_FindEntry(&VAR_INTERNAL->context, name);
+            }
+            if (var == NULL) {
+                return NULL;
+            } else {
+                return ((Var *) Hash_GetValue(var));
+            }
+        } else {
+            return NULL;
+        }
     } else if (var == NULL) {
-	return NULL;
+        return NULL;
     } else {
-	return ((Var *)Hash_GetValue(var));
+        return ((Var *) Hash_GetValue(var));
     }
@@ -485,6 +520,5 @@ VarFind(const char *name, GNode *ctxt, int flags)
 static Boolean
-VarFreeEnv(Var *v, Boolean destroy)
-{
+VarFreeEnv(Var *v, Boolean destroy) {
     if ((v->flags & VAR_FROM_ENV) == 0)
-	return FALSE;
+        return FALSE;
     free(v->name);
@@ -515,7 +549,6 @@ VarFreeEnv(Var *v, Boolean destroy)
 static void
-VarAdd(const char *name, const char *val, GNode *ctxt)
-{
-    Var   	  *v;
-    int		  len;
-    Hash_Entry    *h;
+VarAdd(const char *name, const char *val, GNode *ctxt) {
+    Var *v;
+    int len;
+    Hash_Entry *h;

@@ -524,3 +557,3 @@ VarAdd(const char *name, const char *val, GNode *ctxt)
     len = val ? strlen(val) : 0;
-    Buf_Init(&v->val, len+1);
+    Buf_Init(&v->val, len + 1);
     Buf_AddBytes(&v->val, len, val);
@@ -533,3 +566,3 @@ VarAdd(const char *name, const char *val, GNode *ctxt)
     if (DEBUG(VAR) && (ctxt->flags & INTERNAL) == 0) {
-	fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
+        fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
     }
@@ -551,11 +584,10 @@ VarAdd(const char *name, const char *val, GNode *ctxt)
 void
-Var_Delete(const char *name, GNode *ctxt)
-{
-    Hash_Entry 	  *ln;
+Var_Delete(const char *name, GNode *ctxt) {
+    Hash_Entry *ln;
     char *cp;
-
+
     if (strchr(name, '$')) {
-	cp = Var_Subst(NULL, name, VAR_GLOBAL, VARF_WANTRES);
+        cp = Var_Subst(NULL, name, VAR_GLOBAL, VARF_WANTRES);
     } else {
-	cp = (char *)name;
+        cp = (char *) name;
     }
@@ -563,23 +595,23 @@ Var_Delete(const char *name, GNode *ctxt)
     if (DEBUG(VAR)) {
-	fprintf(debug_file, "%s:delete %s%s\n",
-	    ctxt->name, cp, ln ? "" : " (not found)");
+        fprintf(debug_file, "%s:delete %s%s\n",
+                ctxt->name, cp, ln ? "" : " (not found)");
     }
     if (cp != name) {
-	free(cp);
+        free(cp);
     }
     if (ln != NULL) {
-	Var 	  *v;
+        Var *v;

-	v = (Var *)Hash_GetValue(ln);
-	if ((v->flags & VAR_EXPORTED)) {
-	    unsetenv(v->name);
-	}
-	if (strcmp(MAKE_EXPORTED, v->name) == 0) {
-	    var_exportedVars = VAR_EXPORTED_NONE;
-	}
-	if (v->name != ln->name)
-		free(v->name);
-	Hash_DeleteEntry(&ctxt->context, ln);
-	Buf_Destroy(&v->val, TRUE);
-	free(v);
+        v = (Var *) Hash_GetValue(ln);
+        if ((v->flags & VAR_EXPORTED)) {
+            unsetenv(v->name);
+        }
+        if (strcmp(MAKE_EXPORTED, v->name) == 0) {
+            var_exportedVars = VAR_EXPORTED_NONE;
+        }
+        if (v->name != ln->name)
+            free(v->name);
+        Hash_DeleteEntry(&ctxt->context, ln);
+        Buf_Destroy(&v->val, TRUE);
+        free(v);
     }
@@ -596,4 +628,3 @@ Var_Delete(const char *name, GNode *ctxt)
 static int
-Var_Export1(const char *name, int flags)
-{
+Var_Export1(const char *name, int flags) {
     char tmp[BUFSIZ];
@@ -605,5 +636,5 @@ Var_Export1(const char *name, int flags)
     if (*name == '.')
-	return 0;			/* skip internals */
+        return 0;            /* skip internals */
     if (!name[1]) {
-	/*
+        /*
 	 * A single char.
@@ -613,9 +644,9 @@ Var_Export1(const char *name, int flags)
 	 */
-	switch (name[0]) {
-	case '@':
-	case '%':
-	case '*':
-	case '!':
-	    return 0;
-	}
+        switch (name[0]) {
+            case '@':
+            case '%':
+            case '*':
+            case '!':
+                return 0;
+        }
     }
@@ -623,7 +654,7 @@ Var_Export1(const char *name, int flags)
     if (v == NULL) {
-	return 0;
+        return 0;
     }
     if (!parent &&
-	(v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
-	return 0;			/* nothing to do */
+        (v->flags & (VAR_EXPORTED | VAR_REEXPORT)) == VAR_EXPORTED) {
+        return 0;            /* nothing to do */
     }
@@ -631,4 +662,4 @@ Var_Export1(const char *name, int flags)
     if ((flags & VAR_EXPORT_LITERAL) == 0 && strchr(val, '$')) {
-	if (parent) {
-	    /*
+        if (parent) {
+            /*
 	     * Flag this as something we need to re-export.
@@ -637,7 +668,7 @@ Var_Export1(const char *name, int flags)
 	     */
-	    v->flags |= (VAR_EXPORTED|VAR_REEXPORT);
-	    return 1;
-	}
-	if (v->flags & VAR_IN_USE) {
-	    /*
+            v->flags |= (VAR_EXPORTED | VAR_REEXPORT);
+            return 1;
+        }
+        if (v->flags & VAR_IN_USE) {
+            /*
 	     * We recursed while exporting in a child.
@@ -645,17 +676,17 @@ Var_Export1(const char *name, int flags)
 	     */
-	    return 0;
-	}
-	n = snprintf(tmp, sizeof(tmp), "${%s}", name);
-	if (n < (int)sizeof(tmp)) {
-	    val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
-	    setenv(name, val, 1);
-	    free(val);
-	}
+            return 0;
+        }
+        n = snprintf(tmp, sizeof(tmp), "${%s}", name);
+        if (n < (int) sizeof(tmp)) {
+            val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
+            setenv(name, val, 1);
+            free(val);
+        }
     } else {
-	if (parent) {
-	    v->flags &= ~VAR_REEXPORT;	/* once will do */
-	}
-	if (parent || !(v->flags & VAR_EXPORTED)) {
-	    setenv(name, val, 1);
-	}
+        if (parent) {
+            v->flags &= ~VAR_REEXPORT;    /* once will do */
+        }
+        if (parent || !(v->flags & VAR_EXPORTED)) {
+            setenv(name, val, 1);
+        }
     }
@@ -665,3 +696,3 @@ Var_Export1(const char *name, int flags)
     if (parent) {
-	v->flags |= VAR_EXPORTED;
+        v->flags |= VAR_EXPORTED;
     }
@@ -674,7 +705,6 @@ Var_Export1(const char *name, int flags)
 void
-Var_ExportVars(void)
-{
+Var_ExportVars(void) {
     char tmp[BUFSIZ];
-    Hash_Entry         	*var;
-    Hash_Search 	state;
+    Hash_Entry *var;
+    Hash_Search state;
     Var *v;
@@ -693,15 +723,15 @@ Var_ExportVars(void)
     if (VAR_EXPORTED_NONE == var_exportedVars)
-	return;
+        return;

     if (VAR_EXPORTED_ALL == var_exportedVars) {
-	/*
+        /*
 	 * Ouch! This is crazy...
 	 */
-	for (var = Hash_EnumFirst(&VAR_GLOBAL->context, &state);
-	     var != NULL;
-	     var = Hash_EnumNext(&state)) {
-	    v = (Var *)Hash_GetValue(var);
-	    Var_Export1(v->name, 0);
-	}
-	return;
+        for (var = Hash_EnumFirst(&VAR_GLOBAL->context, &state);
+             var != NULL;
+             var = Hash_EnumNext(&state)) {
+            v = (Var *) Hash_GetValue(var);
+            Var_Export1(v->name, 0);
+        }
+        return;
     }
@@ -711,18 +741,18 @@ Var_ExportVars(void)
     n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
-    if (n < (int)sizeof(tmp)) {
-	char **av;
-	char *as;
-	int ac;
-	int i;
-
-	val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
-	if (*val) {
-	    av = brk_string(val, &ac, FALSE, &as);
-	    for (i = 0; i < ac; i++) {
-		Var_Export1(av[i], 0);
-	    }
-	    free(as);
-	    free(av);
-	}
-	free(val);
+    if (n < (int) sizeof(tmp)) {
+        char **av;
+        char *as;
+        int ac;
+        int i;
+
+        val = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
+        if (*val) {
+            av = brk_string(val, &ac, FALSE, &as);
+            for (i = 0; i < ac; i++) {
+                Var_Export1(av[i], 0);
+            }
+            free(as);
+            free(av);
+        }
+        free(val);
     }
@@ -736,4 +766,3 @@ Var_ExportVars(void)
 void
-Var_Export(char *str, int isExport)
-{
+Var_Export(char *str, int isExport) {
     char *name;
@@ -747,4 +776,4 @@ Var_Export(char *str, int isExport)
     if (isExport && (!str || !str[0])) {
-	var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
-	return;
+        var_exportedVars = VAR_EXPORTED_ALL; /* use with caution! */
+        return;
     }
@@ -753,8 +782,8 @@ Var_Export(char *str, int isExport)
     if (strncmp(str, "-env", 4) == 0) {
-	str += 4;
+        str += 4;
     } else if (strncmp(str, "-literal", 8) == 0) {
-	str += 8;
-	flags |= VAR_EXPORT_LITERAL;
+        str += 8;
+        flags |= VAR_EXPORT_LITERAL;
     } else {
-	flags |= VAR_EXPORT_PARENT;
+        flags |= VAR_EXPORT_PARENT;
     }
@@ -762,7 +791,7 @@ Var_Export(char *str, int isExport)
     if (*val) {
-	av = brk_string(val, &ac, FALSE, &as);
-	for (i = 0; i < ac; i++) {
-	    name = av[i];
-	    if (!name[1]) {
-		/*
+        av = brk_string(val, &ac, FALSE, &as);
+        for (i = 0; i < ac; i++) {
+            name = av[i];
+            if (!name[1]) {
+                /*
 		 * A single char.
@@ -772,20 +801,20 @@ Var_Export(char *str, int isExport)
 		 */
-		switch (name[0]) {
-		case '@':
-		case '%':
-		case '*':
-		case '!':
-		    continue;
-		}
-	    }
-	    if (Var_Export1(name, flags)) {
-		if (VAR_EXPORTED_ALL != var_exportedVars)
-		    var_exportedVars = VAR_EXPORTED_YES;
-		if (isExport && (flags & VAR_EXPORT_PARENT)) {
-		    Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
-		}
-	    }
-	}
-	free(as);
-	free(av);
+                switch (name[0]) {
+                    case '@':
+                    case '%':
+                    case '*':
+                    case '!':
+                        continue;
+                }
+            }
+            if (Var_Export1(name, flags)) {
+                if (VAR_EXPORTED_ALL != var_exportedVars)
+                    var_exportedVars = VAR_EXPORTED_YES;
+                if (isExport && (flags & VAR_EXPORT_PARENT)) {
+                    Var_Append(MAKE_EXPORTED, name, VAR_GLOBAL);
+                }
+            }
+        }
+        free(as);
+        free(av);
     }
@@ -801,4 +830,3 @@ extern char **environ;
 void
-Var_UnExport(char *str)
-{
+Var_UnExport(char *str) {
     char tmp[BUFSIZ];
@@ -810,3 +838,3 @@ Var_UnExport(char *str)
     if (!str || !str[0]) {
-	return; 			/* assert? */
+        return;            /* assert? */
     }
@@ -818,29 +846,29 @@ Var_UnExport(char *str)
     if (unexport_env) {
-	char **newenv;
-
-	cp = getenv(MAKE_LEVEL_ENV);	/* we should preserve this */
-	if (environ == savedEnv) {
-	    /* we have been here before! */
-	    newenv = bmake_realloc(environ, 2 * sizeof(char *));
-	} else {
-	    if (savedEnv) {
-		free(savedEnv);
-		savedEnv = NULL;
-	    }
-	    newenv = bmake_malloc(2 * sizeof(char *));
-	}
-	if (!newenv)
-	    return;
-	/* Note: we cannot safely free() the original environ. */
-	environ = savedEnv = newenv;
-	newenv[0] = NULL;
-	newenv[1] = NULL;
-	if (cp && *cp)
-	    setenv(MAKE_LEVEL_ENV, cp, 1);
+        char **newenv;
+
+        cp = getenv(MAKE_LEVEL_ENV);    /* we should preserve this */
+        if (environ == savedEnv) {
+            /* we have been here before! */
+            newenv = bmake_realloc(environ, 2 * sizeof(char *));
+        } else {
+            if (savedEnv) {
+                free(savedEnv);
+                savedEnv = NULL;
+            }
+            newenv = bmake_malloc(2 * sizeof(char *));
+        }
+        if (!newenv)
+            return;
+        /* Note: we cannot safely free() the original environ. */
+        environ = savedEnv = newenv;
+        newenv[0] = NULL;
+        newenv[1] = NULL;
+        if (cp && *cp)
+            setenv(MAKE_LEVEL_ENV, cp, 1);
     } else {
-	for (; *str != '\n' && isspace((unsigned char) *str); str++)
-	    continue;
-	if (str[0] && str[0] != '\n') {
-	    vlist = str;
-	}
+        for (; *str != '\n' && isspace((unsigned char) *str); str++)
+            continue;
+        if (str[0] && str[0] != '\n') {
+            vlist = str;
+        }
     }
@@ -848,26 +876,26 @@ Var_UnExport(char *str)
     if (!vlist) {
-	/* Using .MAKE.EXPORTED */
-	n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
-	if (n < (int)sizeof(tmp)) {
-	    vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
-	}
+        /* Using .MAKE.EXPORTED */
+        n = snprintf(tmp, sizeof(tmp), "${" MAKE_EXPORTED ":O:u}");
+        if (n < (int) sizeof(tmp)) {
+            vlist = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
+        }
     }
     if (vlist) {
-	Var *v;
-	char **av;
-	char *as;
-	int ac;
-	int i;
-
-	av = brk_string(vlist, &ac, FALSE, &as);
-	for (i = 0; i < ac; i++) {
-	    v = VarFind(av[i], VAR_GLOBAL, 0);
-	    if (!v)
-		continue;
-	    if (!unexport_env &&
-		(v->flags & (VAR_EXPORTED|VAR_REEXPORT)) == VAR_EXPORTED) {
-		unsetenv(v->name);
-	    }
-	    v->flags &= ~(VAR_EXPORTED|VAR_REEXPORT);
-	    /*
+        Var *v;
+        char **av;
+        char *as;
+        int ac;
+        int i;
+
+        av = brk_string(vlist, &ac, FALSE, &as);
+        for (i = 0; i < ac; i++) {
+            v = VarFind(av[i], VAR_GLOBAL, 0);
+            if (!v)
+                continue;
+            if (!unexport_env &&
+                (v->flags & (VAR_EXPORTED | VAR_REEXPORT)) == VAR_EXPORTED) {
+                unsetenv(v->name);
+            }
+            v->flags &= ~(VAR_EXPORTED | VAR_REEXPORT);
+            /*
 	     * If we are unexporting a list,
@@ -877,18 +905,18 @@ Var_UnExport(char *str)
 	     */
-	    if (vlist == str) {
-		n = snprintf(tmp, sizeof(tmp),
-			     "${" MAKE_EXPORTED ":N%s}", v->name);
-		if (n < (int)sizeof(tmp)) {
-		    cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
-		    Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0);
-		    free(cp);
-		}
-	    }
-	}
-	free(as);
-	free(av);
-	if (vlist != str) {
-	    Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
-	    free(vlist);
-	}
+            if (vlist == str) {
+                n = snprintf(tmp, sizeof(tmp),
+                             "${" MAKE_EXPORTED ":N%s}", v->name);
+                if (n < (int) sizeof(tmp)) {
+                    cp = Var_Subst(NULL, tmp, VAR_GLOBAL, VARF_WANTRES);
+                    Var_Set(MAKE_EXPORTED, cp, VAR_GLOBAL, 0);
+                    free(cp);
+                }
+            }
+        }
+        free(as);
+        free(av);
+        if (vlist != str) {
+            Var_Delete(MAKE_EXPORTED, VAR_GLOBAL);
+            free(vlist);
+        }
     }
@@ -925,7 +953,20 @@ Var_UnExport(char *str)
 void
-Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
-{
-    Var   *v;
+Var_Set(const char *name, const char *val, GNode *ctxt, int flags) {
+    Var *v;
     char *expanded_name = NULL;

+
+#if (defined _WIN32 && ! defined __CYGWIN__)
+    char *unix_val;
+    char *error;
+    if (val && strlen(val) > 0 && val[1] == ':'  && (val[2] == '/' || val[2] == '\\')) {
+        unix_val = Cmd_Exec(getUnixPathCmd(val), &error);
+    }
+    else {
+        unix_val = val;
+    }
+#else
+    const char *unix_val = val;
+#endif
+
     /*
@@ -936,25 +977,25 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
     if (strchr(name, '$') != NULL) {
-	expanded_name = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
-	if (expanded_name[0] == 0) {
-	    if (DEBUG(VAR)) {
-		fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) "
-			"name expands to empty string - ignored\n",
-			name, val);
-	    }
-	    free(expanded_name);
-	    return;
-	}
-	name = expanded_name;
+        expanded_name = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
+        if (expanded_name[0] == 0) {
+            if (DEBUG(VAR)) {
+                fprintf(debug_file, "Var_Set(\"%s\", \"%s\", ...) "
+                                    "name expands to empty string - ignored\n",
+                        name, unix_val);
+            }
+            free(expanded_name);
+            return;
+        }
+        name = expanded_name;
     }
     if (ctxt == VAR_GLOBAL) {
-	v = VarFind(name, VAR_CMD, 0);
-	if (v != NULL) {
-	    if ((v->flags & VAR_FROM_CMD)) {
-		if (DEBUG(VAR)) {
-		    fprintf(debug_file, "%s:%s = %s ignored!\n", ctxt->name, name, val);
-		}
-		goto out;
-	    }
-	    VarFreeEnv(v, TRUE);
-	}
+        v = VarFind(name, VAR_CMD, 0);
+        if (v != NULL) {
+            if ((v->flags & VAR_FROM_CMD)) {
+                if (DEBUG(VAR)) {
+                    fprintf(debug_file, "%s:%s = %s ignored!\n", ctxt->name, name, unix_val);
+                }
+                goto out;
+            }
+            VarFreeEnv(v, TRUE);
+        }
     }
@@ -962,4 +1003,4 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
     if (v == NULL) {
-	if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
-	    /*
+        if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
+            /*
 	     * This var would normally prevent the same name being added
@@ -968,16 +1009,16 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
 	     */
-	    Var_Delete(name, VAR_GLOBAL);
-	}
-	VarAdd(name, val, ctxt);
+            Var_Delete(name, VAR_GLOBAL);
+        }
+        VarAdd(name, unix_val, ctxt);
     } else {
-	Buf_Empty(&v->val);
-	if (val)
-	    Buf_AddBytes(&v->val, strlen(val), val);
+        Buf_Empty(&v->val);
+        if (unix_val)
+            Buf_AddBytes(&v->val, strlen(unix_val), unix_val);

-	if (DEBUG(VAR)) {
-	    fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, val);
-	}
-	if ((v->flags & VAR_EXPORTED)) {
-	    Var_Export1(name, VAR_EXPORT_PARENT);
-	}
+        if (DEBUG(VAR)) {
+            fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name, unix_val);
+        }
+        if ((v->flags & VAR_EXPORTED)) {
+            Var_Export1(name, VAR_EXPORT_PARENT);
+        }
     }
@@ -988,9 +1029,9 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
     if (ctxt == VAR_CMD && (flags & VAR_NO_EXPORT) == 0) {
-	if (v == NULL) {
-	    /* we just added it */
-	    v = VarFind(name, ctxt, 0);
-	}
-	if (v != NULL)
-	    v->flags |= VAR_FROM_CMD;
-	/*
+        if (v == NULL) {
+            /* we just added it */
+            v = VarFind(name, ctxt, 0);
+        }
+        if (v != NULL)
+            v->flags |= VAR_FROM_CMD;
+        /*
 	 * If requested, don't export these in the environment
@@ -1000,16 +1041,16 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
 	 */
-	if (varNoExportEnv != TRUE)
-	    setenv(name, val ? val : "", 1);
+        if (varNoExportEnv != TRUE)
+            setenv(name, unix_val ? unix_val : "", 1);

-	Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
+        Var_Append(MAKEOVERRIDES, name, VAR_GLOBAL);
     }
     if (*name == '.') {
-	if (strcmp(name, SAVE_DOLLARS) == 0)
-	    save_dollars = s2Boolean(val, save_dollars);
+        if (strcmp(name, SAVE_DOLLARS) == 0)
+            save_dollars = s2Boolean(unix_val, save_dollars);
     }

- out:
+    out:
     free(expanded_name);
     if (v != NULL)
-	VarFreeEnv(v, TRUE);
+        VarFreeEnv(v, TRUE);
 }
@@ -1044,6 +1085,5 @@ Var_Set(const char *name, const char *val, GNode *ctxt, int flags)
 void
-Var_Append(const char *name, const char *val, GNode *ctxt)
-{
-    Var		   *v;
-    Hash_Entry	   *h;
+Var_Append(const char *name, const char *val, GNode *ctxt) {
+    Var *v;
+    Hash_Entry *h;
     char *expanded_name = NULL;
@@ -1051,30 +1091,30 @@ Var_Append(const char *name, const char *val, GNode *ctxt)
     if (strchr(name, '$') != NULL) {
-	expanded_name = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
-	if (expanded_name[0] == 0) {
-	    if (DEBUG(VAR)) {
-		fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) "
-			"name expands to empty string - ignored\n",
-			name, val);
-	    }
-	    free(expanded_name);
-	    return;
-	}
-	name = expanded_name;
+        expanded_name = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
+        if (expanded_name[0] == 0) {
+            if (DEBUG(VAR)) {
+                fprintf(debug_file, "Var_Append(\"%s\", \"%s\", ...) "
+                                    "name expands to empty string - ignored\n",
+                        name, val);
+            }
+            free(expanded_name);
+            return;
+        }
+        name = expanded_name;
     }

-    v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? (FIND_CMD|FIND_ENV) : 0);
+    v = VarFind(name, ctxt, (ctxt == VAR_GLOBAL) ? (FIND_CMD | FIND_ENV) : 0);

     if (v == NULL) {
-	Var_Set(name, val, ctxt, 0);
+        Var_Set(name, val, ctxt, 0);
     } else if (ctxt == VAR_CMD || !(v->flags & VAR_FROM_CMD)) {
-	Buf_AddByte(&v->val, ' ');
-	Buf_AddBytes(&v->val, strlen(val), val);
+        Buf_AddByte(&v->val, ' ');
+        Buf_AddBytes(&v->val, strlen(val), val);

-	if (DEBUG(VAR)) {
-	    fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name,
-		   Buf_GetAll(&v->val, NULL));
-	}
+        if (DEBUG(VAR)) {
+            fprintf(debug_file, "%s:%s = %s\n", ctxt->name, name,
+                    Buf_GetAll(&v->val, NULL));
+        }

-	if (v->flags & VAR_FROM_ENV) {
-	    /*
+        if (v->flags & VAR_FROM_ENV) {
+            /*
 	     * If the original variable came from the environment, we
@@ -1084,6 +1124,6 @@ Var_Append(const char *name, const char *val, GNode *ctxt)
 	     */
-	    v->flags &= ~VAR_FROM_ENV;
-	    h = Hash_CreateEntry(&ctxt->context, name, NULL);
-	    Hash_SetValue(h, v);
-	}
+            v->flags &= ~VAR_FROM_ENV;
+            h = Hash_CreateEntry(&ctxt->context, name, NULL);
+            Hash_SetValue(h, v);
+        }
     }
@@ -1110,18 +1150,17 @@ Var_Append(const char *name, const char *val, GNode *ctxt)
 Boolean
-Var_Exists(const char *name, GNode *ctxt)
-{
-    Var		  *v;
-    char          *cp;
+Var_Exists(const char *name, GNode *ctxt) {
+    Var *v;
+    char *cp;

     if ((cp = strchr(name, '$')) != NULL) {
-	cp = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
+        cp = Var_Subst(NULL, name, ctxt, VARF_WANTRES);
     }
-    v = VarFind(cp ? cp : name, ctxt, FIND_CMD|FIND_GLOBAL|FIND_ENV);
+    v = VarFind(cp ? cp : name, ctxt, FIND_CMD | FIND_GLOBAL | FIND_ENV);
     free(cp);
     if (v == NULL) {
-	return(FALSE);
+        return (FALSE);
     } else {
-	(void)VarFreeEnv(v, TRUE);
+        (void) VarFreeEnv(v, TRUE);
     }
-    return(TRUE);
+    return (TRUE);
 }
@@ -1145,5 +1184,4 @@ Var_Exists(const char *name, GNode *ctxt)
 char *
-Var_Value(const char *name, GNode *ctxt, char **frp)
-{
-    Var            *v;
+Var_Value(const char *name, GNode *ctxt, char **frp) {
+    Var *v;

@@ -1152,8 +1190,20 @@ Var_Value(const char *name, GNode *ctxt, char **frp)
     if (v != NULL) {
-	char *p = (Buf_GetAll(&v->val, NULL));
-	if (VarFreeEnv(v, FALSE))
-	    *frp = p;
-	return p;
+        char *raw = (Buf_GetAll(&v->val, NULL));
+#if (defined _WIN32 && ! defined __CYGWIN__)
+        char *p;
+        const char *error;
+        if ((raw[1] == ':') && (raw[2] == '/' || raw[2] == '\\')) { // it is windows path
+            p = Cmd_Exec(getUnixPathCmd(raw), &error);
+        }
+        else {
+            p = raw;
+        }
+#else
+      char *p = raw;
+#endif
+        if (VarFreeEnv(v, FALSE))
+            *frp = p;
+        return p;
     } else {
-	return NULL;
+        return NULL;
     }
@@ -1184,5 +1234,4 @@ static Boolean
 VarHead(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	char *word, Boolean addSpace, Buffer *buf,
-	void *dummy MAKE_ATTR_UNUSED)
-{
+        char *word, Boolean addSpace, Buffer *buf,
+        void *dummy MAKE_ATTR_UNUSED) {
     char *slash;
@@ -1191,16 +1240,16 @@ VarHead(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (slash != NULL) {
-	if (addSpace && vpstate->varSpace) {
-	    Buf_AddByte(buf, vpstate->varSpace);
-	}
-	*slash = '\0';
-	Buf_AddBytes(buf, strlen(word), word);
-	*slash = '/';
-	return (TRUE);
+        if (addSpace && vpstate->varSpace) {
+            Buf_AddByte(buf, vpstate->varSpace);
+        }
+        *slash = '\0';
+        Buf_AddBytes(buf, strlen(word), word);
+        *slash = '/';
+        return (TRUE);
     } else {
-	/*
+        /*
 	 * If no directory part, give . (q.v. the POSIX standard)
 	 */
-	if (addSpace && vpstate->varSpace)
-	    Buf_AddByte(buf, vpstate->varSpace);
-	Buf_AddByte(buf, '.');
+        if (addSpace && vpstate->varSpace)
+            Buf_AddByte(buf, vpstate->varSpace);
+        Buf_AddByte(buf, '.');
     }
@@ -1232,5 +1281,4 @@ static Boolean
 VarTail(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	char *word, Boolean addSpace, Buffer *buf,
-	void *dummy MAKE_ATTR_UNUSED)
-{
+        char *word, Boolean addSpace, Buffer *buf,
+        void *dummy MAKE_ATTR_UNUSED) {
     char *slash;
@@ -1238,3 +1286,3 @@ VarTail(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (addSpace && vpstate->varSpace) {
-	Buf_AddByte(buf, vpstate->varSpace);
+        Buf_AddByte(buf, vpstate->varSpace);
     }
@@ -1243,7 +1291,7 @@ VarTail(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (slash != NULL) {
-	*slash++ = '\0';
-	Buf_AddBytes(buf, strlen(slash), slash);
-	slash[-1] = '/';
+        *slash++ = '\0';
+        Buf_AddBytes(buf, strlen(slash), slash);
+        slash[-1] = '/';
     } else {
-	Buf_AddBytes(buf, strlen(word), word);
+        Buf_AddBytes(buf, strlen(word), word);
     }
@@ -1274,5 +1322,4 @@ static Boolean
 VarSuffix(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	  char *word, Boolean addSpace, Buffer *buf,
-	  void *dummy MAKE_ATTR_UNUSED)
-{
+          char *word, Boolean addSpace, Buffer *buf,
+          void *dummy MAKE_ATTR_UNUSED) {
     char *dot;
@@ -1281,9 +1328,9 @@ VarSuffix(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (dot != NULL) {
-	if (addSpace && vpstate->varSpace) {
-	    Buf_AddByte(buf, vpstate->varSpace);
-	}
-	*dot++ = '\0';
-	Buf_AddBytes(buf, strlen(dot), dot);
-	dot[-1] = '.';
-	addSpace = TRUE;
+        if (addSpace && vpstate->varSpace) {
+            Buf_AddByte(buf, vpstate->varSpace);
+        }
+        *dot++ = '\0';
+        Buf_AddBytes(buf, strlen(dot), dot);
+        dot[-1] = '.';
+        addSpace = TRUE;
     }
@@ -1315,5 +1362,4 @@ static Boolean
 VarRoot(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	char *word, Boolean addSpace, Buffer *buf,
-	void *dummy MAKE_ATTR_UNUSED)
-{
+        char *word, Boolean addSpace, Buffer *buf,
+        void *dummy MAKE_ATTR_UNUSED) {
     char *dot;
@@ -1321,3 +1367,3 @@ VarRoot(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (addSpace && vpstate->varSpace) {
-	Buf_AddByte(buf, vpstate->varSpace);
+        Buf_AddByte(buf, vpstate->varSpace);
     }
@@ -1326,7 +1372,7 @@ VarRoot(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (dot != NULL) {
-	*dot = '\0';
-	Buf_AddBytes(buf, strlen(word), word);
-	*dot = '.';
+        *dot = '\0';
+        Buf_AddBytes(buf, strlen(word), word);
+        *dot = '.';
     } else {
-	Buf_AddBytes(buf, strlen(word), word);
+        Buf_AddBytes(buf, strlen(word), word);
     }
@@ -1359,15 +1405,14 @@ static Boolean
 VarMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	 char *word, Boolean addSpace, Buffer *buf,
-	 void *pattern)
-{
+         char *word, Boolean addSpace, Buffer *buf,
+         void *pattern) {
     if (DEBUG(VAR))
-	fprintf(debug_file, "VarMatch [%s] [%s]\n", word, (char *)pattern);
-    if (Str_Match(word, (char *)pattern)) {
-	if (addSpace && vpstate->varSpace) {
-	    Buf_AddByte(buf, vpstate->varSpace);
-	}
-	addSpace = TRUE;
-	Buf_AddBytes(buf, strlen(word), word);
+        fprintf(debug_file, "VarMatch [%s] [%s]\n", word, (char *) pattern);
+    if (Str_Match(word, (char *) pattern)) {
+        if (addSpace && vpstate->varSpace) {
+            Buf_AddByte(buf, vpstate->varSpace);
+        }
+        addSpace = TRUE;
+        Buf_AddBytes(buf, strlen(word), word);
     }
-    return(addSpace);
+    return (addSpace);
 }
@@ -1375,2 +1420,3 @@ VarMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 #ifdef SYSVVARSUB
+
 /*-
@@ -1400,8 +1446,7 @@ static Boolean
 VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
-	     char *word, Boolean addSpace, Buffer *buf,
-	     void *patp)
-{
+             char *word, Boolean addSpace, Buffer *buf,
+             void *patp) {
     int len;
     char *ptr;
-    VarPattern 	  *pat = (VarPattern *)patp;
+    VarPattern *pat = (VarPattern *) patp;
     char *varexp;
@@ -1409,3 +1454,3 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
     if (addSpace && vpstate->varSpace)
-	Buf_AddByte(buf, vpstate->varSpace);
+        Buf_AddByte(buf, vpstate->varSpace);

@@ -1415,10 +1460,11 @@ VarSYSVMatch(GNode *ctx, Var_Parse_State *vpstate,
         varexp = Var_Subst(NULL, pat->rhs, ctx, VARF_WANTRES);
-	Str_SYSVSubst(buf, varexp, ptr, len);
-	free(varexp);
+        Str_SYSVSubst(buf, varexp, ptr, len);
+        free(varexp);
     } else {
-	Buf_AddBytes(buf, strlen(word), word);
+        Buf_AddBytes(buf, strlen(word), word);
     }

-    return(addSpace);
+    return (addSpace);
 }
+
 #endif
@@ -1450,13 +1496,12 @@ static Boolean
 VarNoMatch(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	   char *word, Boolean addSpace, Buffer *buf,
-	   void *pattern)
-{
-    if (!Str_Match(word, (char *)pattern)) {
-	if (addSpace && vpstate->varSpace) {
-	    Buf_AddByte(buf, vpstate->varSpace);
-	}
-	addSpace = TRUE;
-	Buf_AddBytes(buf, strlen(word), word);
+           char *word, Boolean addSpace, Buffer *buf,
+           void *pattern) {
+    if (!Str_Match(word, (char *) pattern)) {
+        if (addSpace && vpstate->varSpace) {
+            Buf_AddByte(buf, vpstate->varSpace);
+        }
+        addSpace = TRUE;
+        Buf_AddBytes(buf, strlen(word), word);
     }
-    return(addSpace);
+    return (addSpace);
 }
@@ -1487,13 +1532,12 @@ static Boolean
 VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	      char *word, Boolean addSpace, Buffer *buf,
-	      void *patternp)
-{
-    int  	wordLen;    /* Length of word */
-    char 	*cp;	    /* General pointer */
-    VarPattern	*pattern = (VarPattern *)patternp;
+              char *word, Boolean addSpace, Buffer *buf,
+              void *patternp) {
+    int wordLen;    /* Length of word */
+    char *cp;        /* General pointer */
+    VarPattern *pattern = (VarPattern *) patternp;

     wordLen = strlen(word);
-    if ((pattern->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) !=
-	(VAR_SUB_ONE|VAR_SUB_MATCHED)) {
-	/*
+    if ((pattern->flags & (VAR_SUB_ONE | VAR_SUB_MATCHED)) !=
+        (VAR_SUB_ONE | VAR_SUB_MATCHED)) {
+        /*
 	 * Still substituting -- break it down into simple anchored cases
@@ -1501,10 +1545,10 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 	 */
-	if ((pattern->flags & VAR_MATCH_START) &&
-	    (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) {
-		/*
+        if ((pattern->flags & VAR_MATCH_START) &&
+            (strncmp(word, pattern->lhs, pattern->leftLen) == 0)) {
+            /*
 		 * Anchored at start and beginning of word matches pattern
 		 */
-		if ((pattern->flags & VAR_MATCH_END) &&
-		    (wordLen == pattern->leftLen)) {
-			/*
+            if ((pattern->flags & VAR_MATCH_END) &&
+                (wordLen == pattern->leftLen)) {
+                /*
 			 * Also anchored at end and matches to the end (word
@@ -1513,37 +1557,37 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 			 */
-			if (pattern->rightLen != 0) {
-			    if (addSpace && vpstate->varSpace) {
-				Buf_AddByte(buf, vpstate->varSpace);
-			    }
-			    addSpace = TRUE;
-			    Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
-			}
-			pattern->flags |= VAR_SUB_MATCHED;
-		} else if (pattern->flags & VAR_MATCH_END) {
-		    /*
+                if (pattern->rightLen != 0) {
+                    if (addSpace && vpstate->varSpace) {
+                        Buf_AddByte(buf, vpstate->varSpace);
+                    }
+                    addSpace = TRUE;
+                    Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+                }
+                pattern->flags |= VAR_SUB_MATCHED;
+            } else if (pattern->flags & VAR_MATCH_END) {
+                /*
 		     * Doesn't match to end -- copy word wholesale
 		     */
-		    goto nosub;
-		} else {
-		    /*
+                goto nosub;
+            } else {
+                /*
 		     * Matches at start but need to copy in trailing characters
 		     */
-		    if ((pattern->rightLen + wordLen - pattern->leftLen) != 0){
-			if (addSpace && vpstate->varSpace) {
-			    Buf_AddByte(buf, vpstate->varSpace);
-			}
-			addSpace = TRUE;
-		    }
-		    Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
-		    Buf_AddBytes(buf, wordLen - pattern->leftLen,
-				 (word + pattern->leftLen));
-		    pattern->flags |= VAR_SUB_MATCHED;
-		}
-	} else if (pattern->flags & VAR_MATCH_START) {
-	    /*
+                if ((pattern->rightLen + wordLen - pattern->leftLen) != 0) {
+                    if (addSpace && vpstate->varSpace) {
+                        Buf_AddByte(buf, vpstate->varSpace);
+                    }
+                    addSpace = TRUE;
+                }
+                Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+                Buf_AddBytes(buf, wordLen - pattern->leftLen,
+                             (word + pattern->leftLen));
+                pattern->flags |= VAR_SUB_MATCHED;
+            }
+        } else if (pattern->flags & VAR_MATCH_START) {
+            /*
 	     * Had to match at start of word and didn't -- copy whole word.
 	     */
-	    goto nosub;
-	} else if (pattern->flags & VAR_MATCH_END) {
-	    /*
+            goto nosub;
+        } else if (pattern->flags & VAR_MATCH_END) {
+            /*
 	     * Anchored at end, Find only place match could occur (leftLen
@@ -1553,6 +1597,6 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 	     */
-	    cp = word + (wordLen - pattern->leftLen);
-	    if ((cp >= word) &&
-		(strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) {
-		/*
+            cp = word + (wordLen - pattern->leftLen);
+            if ((cp >= word) &&
+                (strncmp(cp, pattern->lhs, pattern->leftLen) == 0)) {
+                /*
 		 * Match found. If we will place characters in the buffer,
@@ -1562,19 +1606,19 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 		 */
-		if (((cp - word) + pattern->rightLen) != 0) {
-		    if (addSpace && vpstate->varSpace) {
-			Buf_AddByte(buf, vpstate->varSpace);
-		    }
-		    addSpace = TRUE;
-		}
-		Buf_AddBytes(buf, cp - word, word);
-		Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
-		pattern->flags |= VAR_SUB_MATCHED;
-	    } else {
-		/*
+                if (((cp - word) + pattern->rightLen) != 0) {
+                    if (addSpace && vpstate->varSpace) {
+                        Buf_AddByte(buf, vpstate->varSpace);
+                    }
+                    addSpace = TRUE;
+                }
+                Buf_AddBytes(buf, cp - word, word);
+                Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+                pattern->flags |= VAR_SUB_MATCHED;
+            } else {
+                /*
 		 * Had to match at end and didn't. Copy entire word.
 		 */
-		goto nosub;
-	    }
-	} else {
-	    /*
+                goto nosub;
+            }
+        } else {
+            /*
 	     * Pattern is unanchored: search for the pattern in the word using
@@ -1589,36 +1633,36 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 	     */
-	    Boolean done;
-	    int origSize;
-
-	    done = FALSE;
-	    origSize = Buf_Size(buf);
-	    while (!done) {
-		cp = Str_FindSubstring(word, pattern->lhs);
-		if (cp != NULL) {
-		    if (addSpace && (((cp - word) + pattern->rightLen) != 0)){
-			Buf_AddByte(buf, vpstate->varSpace);
-			addSpace = FALSE;
-		    }
-		    Buf_AddBytes(buf, cp-word, word);
-		    Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
-		    wordLen -= (cp - word) + pattern->leftLen;
-		    word = cp + pattern->leftLen;
-		    if (wordLen == 0) {
-			done = TRUE;
-		    }
-		    if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
-			done = TRUE;
-		    }
-		    pattern->flags |= VAR_SUB_MATCHED;
-		} else {
-		    done = TRUE;
-		}
-	    }
-	    if (wordLen != 0) {
-		if (addSpace && vpstate->varSpace) {
-		    Buf_AddByte(buf, vpstate->varSpace);
-		}
-		Buf_AddBytes(buf, wordLen, word);
-	    }
-	    /*
+            Boolean done;
+            int origSize;
+
+            done = FALSE;
+            origSize = Buf_Size(buf);
+            while (!done) {
+                cp = Str_FindSubstring(word, pattern->lhs);
+                if (cp != NULL) {
+                    if (addSpace && (((cp - word) + pattern->rightLen) != 0)) {
+                        Buf_AddByte(buf, vpstate->varSpace);
+                        addSpace = FALSE;
+                    }
+                    Buf_AddBytes(buf, cp - word, word);
+                    Buf_AddBytes(buf, pattern->rightLen, pattern->rhs);
+                    wordLen -= (cp - word) + pattern->leftLen;
+                    word = cp + pattern->leftLen;
+                    if (wordLen == 0) {
+                        done = TRUE;
+                    }
+                    if ((pattern->flags & VAR_SUB_GLOBAL) == 0) {
+                        done = TRUE;
+                    }
+                    pattern->flags |= VAR_SUB_MATCHED;
+                } else {
+                    done = TRUE;
+                }
+            }
+            if (wordLen != 0) {
+                if (addSpace && vpstate->varSpace) {
+                    Buf_AddByte(buf, vpstate->varSpace);
+                }
+                Buf_AddBytes(buf, wordLen, word);
+            }
+            /*
 	     * If added characters to the buffer, need to add a space
@@ -1627,12 +1671,12 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 	     */
-	    return ((Buf_Size(buf) != origSize) || addSpace);
-	}
-	return (addSpace);
+            return ((Buf_Size(buf) != origSize) || addSpace);
+        }
+        return (addSpace);
     }
- nosub:
+    nosub:
     if (addSpace && vpstate->varSpace) {
-	Buf_AddByte(buf, vpstate->varSpace);
+        Buf_AddByte(buf, vpstate->varSpace);
     }
     Buf_AddBytes(buf, wordLen, word);
-    return(TRUE);
+    return (TRUE);
 }
@@ -1640,2 +1684,3 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 #ifndef NO_REGEX
+
 /*-
@@ -1654,4 +1699,3 @@ VarSubstitute(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
 static void
-VarREError(int reerr, regex_t *pat, const char *str)
-{
+VarREError(int reerr, regex_t *pat, const char *str) {
     char *errbuf;
@@ -1683,6 +1727,5 @@ static Boolean
 VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED,
-		Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
-		char *word, Boolean addSpace, Buffer *buf,
-		void *patternp)
-{
+                Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
+                char *word, Boolean addSpace, Buffer *buf,
+                void *patternp) {
     VarREPattern *pat;
@@ -1694,6 +1737,6 @@ VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED,

-#define MAYBE_ADD_SPACE()		\
-	if (addSpace && !added)		\
-	    Buf_AddByte(buf, ' ');	\
-	added = 1
+#define MAYBE_ADD_SPACE()        \
+    if (addSpace && !added)        \
+        Buf_AddByte(buf, ' ');    \
+    added = 1

@@ -1703,8 +1746,8 @@ VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED,

-    if ((pat->flags & (VAR_SUB_ONE|VAR_SUB_MATCHED)) ==
-	(VAR_SUB_ONE|VAR_SUB_MATCHED))
-	xrv = REG_NOMATCH;
+    if ((pat->flags & (VAR_SUB_ONE | VAR_SUB_MATCHED)) ==
+        (VAR_SUB_ONE | VAR_SUB_MATCHED))
+        xrv = REG_NOMATCH;
     else {
-    tryagain:
-	xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
+        tryagain:
+        xrv = regexec(&pat->re, wp, pat->nsub, pat->matches, flags);
     }
@@ -1712,88 +1755,87 @@ VarRESubstitute(GNode *ctx MAKE_ATTR_UNUSED,
     switch (xrv) {
-    case 0:
-	pat->flags |= VAR_SUB_MATCHED;
-	if (pat->matches[0].rm_so > 0) {
-	    MAYBE_ADD_SPACE();
-	    Buf_AddBytes(buf, pat->matches[0].rm_so, wp);
-	}
-
-	for (rp = pat->replace; *rp; rp++) {
-	    if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
-		MAYBE_ADD_SPACE();
-		Buf_AddByte(buf,rp[1]);
-		rp++;
-	    }
-	    else if ((*rp == '&') ||
-		((*rp == '\\') && isdigit((unsigned char)rp[1]))) {
-		int n;
-		const char *subbuf;
-		int sublen;
-		char errstr[3];
-
-		if (*rp == '&') {
-		    n = 0;
-		    errstr[0] = '&';
-		    errstr[1] = '\0';
-		} else {
-		    n = rp[1] - '0';
-		    errstr[0] = '\\';
-		    errstr[1] = rp[1];
-		    errstr[2] = '\0';
-		    rp++;
-		}
-
-		if (n > pat->nsub) {
-		    Error("No subexpression %s", &errstr[0]);
-		    subbuf = "";
-		    sublen = 0;
-		} else if ((pat->matches[n].rm_so == -1) &&
-			   (pat->matches[n].rm_eo == -1)) {
-		    Error("No match for subexpression %s", &errstr[0]);
-		    subbuf = "";
-		    sublen = 0;
-	        } else {
-		    subbuf = wp + pat->matches[n].rm_so;
-		    sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
-		}
-
-		if (sublen > 0) {
-		    MAYBE_ADD_SPACE();
-		    Buf_AddBytes(buf, sublen, subbuf);
-		}
-	    } else {
-		MAYBE_ADD_SPACE();
-		Buf_AddByte(buf, *rp);
-	    }
-	}
-	wp += pat->matches[0].rm_eo;
-	if (pat->flags & VAR_SUB_GLOBAL) {
-	    flags |= REG_NOTBOL;
-	    if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
-		MAYBE_ADD_SPACE();
-		Buf_AddByte(buf, *wp);
-		wp++;
-
-	    }
-	    if (*wp)
-		goto tryagain;
-	}
-	if (*wp) {
-	    MAYBE_ADD_SPACE();
-	    Buf_AddBytes(buf, strlen(wp), wp);
-	}
-	break;
-    default:
-	VarREError(xrv, &pat->re, "Unexpected regex error");
-       /* fall through */
-    case REG_NOMATCH:
-	if (*wp) {
-	    MAYBE_ADD_SPACE();
-	    Buf_AddBytes(buf,strlen(wp),wp);
-	}
-	break;
-    }
-    return(addSpace||added);
+        case 0:
+            pat->flags |= VAR_SUB_MATCHED;
+            if (pat->matches[0].rm_so > 0) {
+                MAYBE_ADD_SPACE();
+                Buf_AddBytes(buf, pat->matches[0].rm_so, wp);
+            }
+
+            for (rp = pat->replace; *rp; rp++) {
+                if ((*rp == '\\') && ((rp[1] == '&') || (rp[1] == '\\'))) {
+                    MAYBE_ADD_SPACE();
+                    Buf_AddByte(buf, rp[1]);
+                    rp++;
+                } else if ((*rp == '&') ||
+                           ((*rp == '\\') && isdigit((unsigned char) rp[1]))) {
+                    int n;
+                    const char *subbuf;
+                    int sublen;
+                    char errstr[3];
+
+                    if (*rp == '&') {
+                        n = 0;
+                        errstr[0] = '&';
+                        errstr[1] = '\0';
+                    } else {
+                        n = rp[1] - '0';
+                        errstr[0] = '\\';
+                        errstr[1] = rp[1];
+                        errstr[2] = '\0';
+                        rp++;
+                    }
+
+                    if (n > pat->nsub) {
+                        Error("No subexpression %s", &errstr[0]);
+                        subbuf = "";
+                        sublen = 0;
+                    } else if ((pat->matches[n].rm_so == -1) &&
+                               (pat->matches[n].rm_eo == -1)) {
+                        Error("No match for subexpression %s", &errstr[0]);
+                        subbuf = "";
+                        sublen = 0;
+                    } else {
+                        subbuf = wp + pat->matches[n].rm_so;
+                        sublen = pat->matches[n].rm_eo - pat->matches[n].rm_so;
+                    }
+
+                    if (sublen > 0) {
+                        MAYBE_ADD_SPACE();
+                        Buf_AddBytes(buf, sublen, subbuf);
+                    }
+                } else {
+                    MAYBE_ADD_SPACE();
+                    Buf_AddByte(buf, *rp);
+                }
+            }
+            wp += pat->matches[0].rm_eo;
+            if (pat->flags & VAR_SUB_GLOBAL) {
+                flags |= REG_NOTBOL;
+                if (pat->matches[0].rm_so == 0 && pat->matches[0].rm_eo == 0) {
+                    MAYBE_ADD_SPACE();
+                    Buf_AddByte(buf, *wp);
+                    wp++;
+
+                }
+                if (*wp)
+                    goto tryagain;
+            }
+            if (*wp) {
+                MAYBE_ADD_SPACE();
+                Buf_AddBytes(buf, strlen(wp), wp);
+            }
+            break;
+        default:
+            VarREError(xrv, &pat->re, "Unexpected regex error");
+            /* fall through */
+        case REG_NOMATCH:
+            if (*wp) {
+                MAYBE_ADD_SPACE();
+                Buf_AddBytes(buf, strlen(wp), wp);
+            }
+            break;
+    }
+    return (addSpace || added);
 }
-#endif

+#endif

@@ -1824,7 +1866,6 @@ static Boolean
 VarLoopExpand(GNode *ctx MAKE_ATTR_UNUSED,
-	      Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
-	      char *word, Boolean addSpace, Buffer *buf,
-	      void *loopp)
-{
-    VarLoop_t	*loop = (VarLoop_t *)loopp;
+              Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
+              char *word, Boolean addSpace, Buffer *buf,
+              void *loopp) {
+    VarLoop_t *loop = (VarLoop_t *) loopp;
     char *s;
@@ -1841,3 +1882,3 @@ VarLoopExpand(GNode *ctx MAKE_ATTR_UNUSED,
         }
-	free(s);
+        free(s);
     }
@@ -1868,10 +1909,9 @@ static char *
 VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	       const char *str, VarSelectWords_t *seldata)
-{
-    Buffer  	  buf;		    /* Buffer for the new string */
-    Boolean 	  addSpace; 	    /* TRUE if need to add a space to the
+               const char *str, VarSelectWords_t *seldata) {
+    Buffer buf;            /* Buffer for the new string */
+    Boolean addSpace;        /* TRUE if need to add a space to the
 				     * buffer before adding the trimmed
 				     * word */
-    char **av;			    /* word list */
-    char *as;			    /* word list memory */
+    char **av;                /* word list */
+    char *as;                /* word list memory */
     int ac, i;
@@ -1883,10 +1923,10 @@ VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (vpstate->oneBigWord) {
-	/* fake what brk_string() would do if there were only one word */
-	ac = 1;
-    	av = bmake_malloc((ac + 1) * sizeof(char *));
-	as = bmake_strdup(str);
-	av[0] = as;
-	av[1] = NULL;
+        /* fake what brk_string() would do if there were only one word */
+        ac = 1;
+        av = bmake_malloc((ac + 1) * sizeof(char *));
+        as = bmake_strdup(str);
+        av[0] = as;
+        av[1] = NULL;
     } else {
-	av = brk_string(str, &ac, FALSE, &as);
+        av = brk_string(str, &ac, FALSE, &as);
     }
@@ -1900,5 +1940,5 @@ VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (seldata->start < 0)
-	seldata->start = ac + seldata->start + 1;
+        seldata->start = ac + seldata->start + 1;
     if (seldata->end < 0)
-	seldata->end = ac + seldata->end + 1;
+        seldata->end = ac + seldata->end + 1;

@@ -1908,9 +1948,9 @@ VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     if (seldata->start > seldata->end) {
-	start = MIN(ac, seldata->start) - 1;
-	end = MAX(0, seldata->end - 1);
-	step = -1;
+        start = MIN(ac, seldata->start) - 1;
+        end = MAX(0, seldata->end - 1);
+        step = -1;
     } else {
-	start = MAX(0, seldata->start - 1);
-	end = MIN(ac, seldata->end);
-	step = 1;
+        start = MAX(0, seldata->start - 1);
+        end = MIN(ac, seldata->end);
+        step = 1;
     }
@@ -1918,11 +1958,11 @@ VarSelectWords(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
     for (i = start;
-	 (step < 0 && i >= end) || (step > 0 && i < end);
-	 i += step) {
-	if (av[i] && *av[i]) {
-	    if (addSpace && vpstate->varSpace) {
-		Buf_AddByte(&buf, vpstate->varSpace);
-	    }
-	    Buf_AddBytes(&buf, strlen(av[i]), av[i]);
-	    addSpace = TRUE;
-	}
+         (step < 0 && i >= end) || (step > 0 && i < end);
+         i += step) {
+        if (av[i] && *av[i]) {
+            if (addSpace && vpstate->varSpace) {
+                Buf_AddByte(&buf, vpstate->varSpace);
+            }
+            Buf_AddBytes(&buf, strlen(av[i]), av[i]);
+            addSpace = TRUE;
+        }
     }
@@ -1943,19 +1983,18 @@ static Boolean
 VarRealpath(GNode *ctx MAKE_ATTR_UNUSED, Var_Parse_State *vpstate,
-	    char *word, Boolean addSpace, Buffer *buf,
-	    void *patternp MAKE_ATTR_UNUSED)
-{
-	struct stat st;
-	char rbuf[MAXPATHLEN];
-	char *rp;
-
-	if (addSpace && vpstate->varSpace) {
-	    Buf_AddByte(buf, vpstate->varSpace);
-	}
-	addSpace = TRUE;
-	rp = cached_realpath(word, rbuf);
-	if (rp && *rp == '/' && stat(rp, &st) == 0)
-		word = rp;
-
-	Buf_AddBytes(buf, strlen(word), word);
-	return(addSpace);
+            char *word, Boolean addSpace, Buffer *buf,
+            void *patternp MAKE_ATTR_UNUSED) {
+    struct stat st;
+    char rbuf[MAXPATHLEN];
+    char *rp;
+
+    if (addSpace && vpstate->varSpace) {
+        Buf_AddByte(buf, vpstate->varSpace);
+    }
+    addSpace = TRUE;
+    rp = cached_realpath(word, rbuf);
+    if (rp && *rp == '/' && stat(rp, &st) == 0)
+        word = rp;
+
+    Buf_AddBytes(buf, strlen(word), word);
+    return (addSpace);
 }
@@ -1983,13 +2022,12 @@ static char *
 VarModify(GNode *ctx, Var_Parse_State *vpstate,
-    const char *str,
-    Boolean (*modProc)(GNode *, Var_Parse_State *, char *,
-		       Boolean, Buffer *, void *),
-    void *datum)
-{
-    Buffer  	  buf;		    /* Buffer for the new string */
-    Boolean 	  addSpace; 	    /* TRUE if need to add a space to the
+          const char *str,
+          Boolean (*modProc)(GNode *, Var_Parse_State *, char *,
+                             Boolean, Buffer *, void *),
+          void *datum) {
+    Buffer buf;            /* Buffer for the new string */
+    Boolean addSpace;        /* TRUE if need to add a space to the
 				     * buffer before adding the trimmed
 				     * word */
-    char **av;			    /* word list */
-    char *as;			    /* word list memory */
+    char **av;                /* word list */
+    char *as;                /* word list memory */
     int ac, i;
@@ -2000,10 +2038,10 @@ VarModify(GNode *ctx, Var_Parse_State *vpstate,
     if (vpstate->oneBigWord) {
-	/* fake what brk_string() would do if there were only one word */
-	ac = 1;
-    	av = bmake_malloc((ac + 1) * sizeof(char *));
-	as = bmake_strdup(str);
-	av[0] = as;
-	av[1] = NULL;
+        /* fake what brk_string() would do if there were only one word */
+        ac = 1;
+        av = bmake_malloc((ac + 1) * sizeof(char *));
+        as = bmake_strdup(str);
+        av[0] = as;
+        av[1] = NULL;
     } else {
-	av = brk_string(str, &ac, FALSE, &as);
+        av = brk_string(str, &ac, FALSE, &as);
     }
@@ -2011,3 +2049,3 @@ VarModify(GNode *ctx, Var_Parse_State *vpstate,
     for (i = 0; i < ac; i++) {
-	addSpace = (*modProc)(ctx, vpstate, av[i], addSpace, &buf, datum);
+        addSpace = (*modProc)(ctx, vpstate, av[i], addSpace, &buf, datum);
     }
@@ -2022,6 +2060,5 @@ VarModify(GNode *ctx, Var_Parse_State *vpstate,
 static int
-VarWordCompare(const void *a, const void *b)
-{
-	int r = strcmp(*(const char * const *)a, *(const char * const *)b);
-	return r;
+VarWordCompare(const void *a, const void *b) {
+    int r = strcmp(*(const char *const *) a, *(const char *const *) b);
+    return r;
 }
@@ -2046,7 +2083,6 @@ VarWordCompare(const void *a, const void *b)
 static char *
-VarOrder(const char *str, const char otype)
-{
-    Buffer  	  buf;		    /* Buffer for the new string */
-    char **av;			    /* word list [first word does not count] */
-    char *as;			    /* word list memory */
+VarOrder(const char *str, const char otype) {
+    Buffer buf;            /* Buffer for the new string */
+    char **av;                /* word list [first word does not count] */
+    char *as;                /* word list memory */
     int ac, i;
@@ -2058,12 +2094,12 @@ VarOrder(const char *str, const char otype)
     if (ac > 0)
-	switch (otype) {
-	case 's':	/* sort alphabetically */
-	    qsort(av, ac, sizeof(char *), VarWordCompare);
-	    break;
-	case 'x':	/* randomize */
-	{
-	    int rndidx;
-	    char *t;
-
-	    /*
+        switch (otype) {
+            case 's':    /* sort alphabetically */
+                qsort(av, ac, sizeof(char *), VarWordCompare);
+                break;
+            case 'x':    /* randomize */
+            {
+                int rndidx;
+                char *t;
+
+                /*
 	     * We will use [ac..2] range for mod factors. This will produce
@@ -2073,17 +2109,17 @@ VarOrder(const char *str, const char otype)
 	     */
-	    for (i = ac-1; i > 0; i--) {
-		rndidx = random() % (i + 1);
-		if (i != rndidx) {
-		    t = av[i];
-		    av[i] = av[rndidx];
-		    av[rndidx] = t;
-		}
-	    }
-	}
-	} /* end of switch */
+                for (i = ac - 1; i > 0; i--) {
+                    rndidx = random() % (i + 1);
+                    if (i != rndidx) {
+                        t = av[i];
+                        av[i] = av[rndidx];
+                        av[rndidx] = t;
+                    }
+                }
+            }
+        } /* end of switch */

     for (i = 0; i < ac; i++) {
-	Buf_AddBytes(&buf, strlen(av[i]), av[i]);
-	if (i != ac - 1)
-	    Buf_AddByte(&buf, ' ');
+        Buf_AddBytes(&buf, strlen(av[i]), av[i]);
+        if (i != ac - 1)
+            Buf_AddByte(&buf, ' ');
     }
@@ -2114,8 +2150,7 @@ VarOrder(const char *str, const char otype)
 static char *
-VarUniq(const char *str)
-{
-    Buffer	  buf;		    /* Buffer for new string */
-    char 	**av;		    /* List of words to affect */
-    char 	 *as;		    /* Word list memory */
-    int 	  ac, i, j;
+VarUniq(const char *str) {
+    Buffer buf;            /* Buffer for new string */
+    char **av;            /* List of words to affect */
+    char *as;            /* Word list memory */
+    int ac, i, j;

@@ -2125,6 +2160,6 @@ VarUniq(const char *str)
     if (ac > 1) {
-	for (j = 0, i = 1; i < ac; i++)
-	    if (strcmp(av[i], av[j]) != 0 && (++j != i))
-		av[j] = av[i];
-	ac = j + 1;
+        for (j = 0, i = 1; i < ac; i++)
+            if (strcmp(av[i], av[j]) != 0 && (++j != i))
+                av[j] = av[i];
+        ac = j + 1;
     }
@@ -2132,5 +2167,5 @@ VarUniq(const char *str)
     for (i = 0; i < ac; i++) {
-	Buf_AddBytes(&buf, strlen(av[i]), av[i]);
-	if (i != ac - 1)
-	    Buf_AddByte(&buf, ' ');
+        Buf_AddBytes(&buf, strlen(av[i]), av[i]);
+        if (i != ac - 1)
+            Buf_AddByte(&buf, ' ');
     }
@@ -2158,9 +2193,8 @@ VarUniq(const char *str)
 static char *
-VarRange(const char *str, int ac)
-{
-    Buffer	  buf;		    /* Buffer for new string */
-    char	  tmp[32];	    /* each element */
-    char 	**av;		    /* List of words to affect */
-    char 	 *as;		    /* Word list memory */
-    int 	  i, n;
+VarRange(const char *str, int ac) {
+    Buffer buf;            /* Buffer for new string */
+    char tmp[32];        /* each element */
+    char **av;            /* List of words to affect */
+    char *as;            /* Word list memory */
+    int i, n;

@@ -2168,14 +2202,14 @@ VarRange(const char *str, int ac)
     if (ac > 0) {
-	as = NULL;
-	av = NULL;
+        as = NULL;
+        av = NULL;
     } else {
-	av = brk_string(str, &ac, FALSE, &as);
+        av = brk_string(str, &ac, FALSE, &as);
     }
     for (i = 0; i < ac; i++) {
-	n = snprintf(tmp, sizeof(tmp), "%d", 1 + i);
-	if (n >= (int)sizeof(tmp))
-	    break;
-	Buf_AddBytes(&buf, n, tmp);
-	if (i != ac - 1)
-	    Buf_AddByte(&buf, ' ');
+        n = snprintf(tmp, sizeof(tmp), "%d", 1 + i);
+        if (n >= (int) sizeof(tmp))
+            break;
+        Buf_AddBytes(&buf, n, tmp);
+        if (i != ac - 1)
+            Buf_AddByte(&buf, ' ');
     }
@@ -2213,5 +2247,4 @@ static char *
 VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
-	      int flags, const char **tstr, int delim, int *vflags,
-	      int *length, VarPattern *pattern)
-{
+              int flags, const char **tstr, int delim, int *vflags,
+              int *length, VarPattern *pattern) {
     const char *cp;
@@ -2224,3 +2257,3 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
     if (length == NULL)
-	length = &junk;
+        length = &junk;

@@ -2237,11 +2270,11 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
     for (cp = *tstr; *cp && (*cp != delim); cp++) {
-	if (IS_A_MATCH(cp, delim)) {
-	    Buf_AddByte(&buf, cp[1]);
-	    cp++;
-	} else if (*cp == '$') {
-	    if (cp[1] == delim) {
-		if (vflags == NULL)
-		    Buf_AddByte(&buf, *cp);
-		else
-		    /*
+        if (IS_A_MATCH(cp, delim)) {
+            Buf_AddByte(&buf, cp[1]);
+            cp++;
+        } else if (*cp == '$') {
+            if (cp[1] == delim) {
+                if (vflags == NULL)
+                    Buf_AddByte(&buf, *cp);
+                else
+                    /*
 		     * Unescaped $ at end of pattern => anchor
@@ -2249,10 +2282,10 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
 		     */
-		    *vflags |= VAR_MATCH_END;
-	    } else {
-		if (vflags == NULL || (*vflags & VAR_NOSUBST) == 0) {
-		    char   *cp2;
-		    int     len;
-		    void   *freeIt;
-
-		    /*
+                    *vflags |= VAR_MATCH_END;
+            } else {
+                if (vflags == NULL || (*vflags & VAR_NOSUBST) == 0) {
+                    char *cp2;
+                    int len;
+                    void *freeIt;
+
+                    /*
 		     * If unescaped dollar sign not before the
@@ -2261,12 +2294,12 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
 		     */
-		    cp2 = Var_Parse(cp, ctxt, errnum | VARF_WANTRES, &len,
-			&freeIt);
-		    Buf_AddBytes(&buf, strlen(cp2), cp2);
-		    free(freeIt);
-		    cp += len - 1;
-		} else {
-		    const char *cp2 = &cp[1];
-
-		    if (*cp2 == PROPEN || *cp2 == BROPEN) {
-			/*
+                    cp2 = Var_Parse(cp, ctxt, errnum | VARF_WANTRES, &len,
+                                    &freeIt);
+                    Buf_AddBytes(&buf, strlen(cp2), cp2);
+                    free(freeIt);
+                    cp += len - 1;
+                } else {
+                    const char *cp2 = &cp[1];
+
+                    if (*cp2 == PROPEN || *cp2 == BROPEN) {
+                        /*
 			 * Find the end of this variable reference
@@ -2275,25 +2308,24 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
 			 */
-			int have = *cp2;
-			int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE;
-			int depth = 1;
-
-			for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
-			    if (cp2[-1] != '\\') {
-				if (*cp2 == have)
-				    ++depth;
-				if (*cp2 == want)
-				    --depth;
-			    }
-			}
-			Buf_AddBytes(&buf, cp2 - cp, cp);
-			cp = --cp2;
-		    } else
-			Buf_AddByte(&buf, *cp);
-		}
-	    }
-	}
-	else if (pattern && *cp == '&')
-	    Buf_AddBytes(&buf, pattern->leftLen, pattern->lhs);
-	else
-	    Buf_AddByte(&buf, *cp);
+                        int have = *cp2;
+                        int want = (*cp2 == PROPEN) ? PRCLOSE : BRCLOSE;
+                        int depth = 1;
+
+                        for (++cp2; *cp2 != '\0' && depth > 0; ++cp2) {
+                            if (cp2[-1] != '\\') {
+                                if (*cp2 == have)
+                                    ++depth;
+                                if (*cp2 == want)
+                                    --depth;
+                            }
+                        }
+                        Buf_AddBytes(&buf, cp2 - cp, cp);
+                        cp = --cp2;
+                    } else
+                        Buf_AddByte(&buf, *cp);
+                }
+            }
+        } else if (pattern && *cp == '&')
+            Buf_AddBytes(&buf, pattern->leftLen, pattern->lhs);
+        else
+            Buf_AddByte(&buf, *cp);
     }
@@ -2301,5 +2333,5 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
     if (*cp != delim) {
-	*tstr = cp;
-	*length = 0;
-	return NULL;
+        *tstr = cp;
+        *length = 0;
+        return NULL;
     }
@@ -2310,3 +2342,3 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
     if (DEBUG(VAR))
-	fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr);
+        fprintf(debug_file, "Modifier pattern: \"%s\"\n", rstr);
     return rstr;
@@ -2329,7 +2361,6 @@ VarGetPattern(GNode *ctxt, Var_Parse_State *vpstate MAKE_ATTR_UNUSED,
 static char *
-VarQuote(char *str, Boolean quoteDollar)
-{
+VarQuote(char *str, Boolean quoteDollar) {

-    Buffer  	  buf;
-    const char	*newline;
+    Buffer buf;
+    const char *newline;
     size_t nlen;
@@ -2337,3 +2368,3 @@ VarQuote(char *str, Boolean quoteDollar)
     if ((newline = Shell_GetNewline()) == NULL)
-	    newline = "\\\n";
+        newline = "\\\n";
     nlen = strlen(newline);
@@ -2343,11 +2374,11 @@ VarQuote(char *str, Boolean quoteDollar)
     for (; *str != '\0'; str++) {
-	if (*str == '\n') {
-	    Buf_AddBytes(&buf, nlen, newline);
-	    continue;
-	}
-	if (isspace((unsigned char)*str) || ismeta((unsigned char)*str))
-	    Buf_AddByte(&buf, '\\');
-	Buf_AddByte(&buf, *str);
-	if (quoteDollar && *str == '$')
-	    Buf_AddBytes(&buf, 2, "\\$");
+        if (*str == '\n') {
+            Buf_AddBytes(&buf, nlen, newline);
+            continue;
+        }
+        if (isspace((unsigned char) *str) || ismeta((unsigned char) *str))
+            Buf_AddByte(&buf, '\\');
+        Buf_AddByte(&buf, *str);
+        if (quoteDollar && *str == '$')
+            Buf_AddBytes(&buf, 2, "\\$");
     }
@@ -2356,3 +2387,3 @@ VarQuote(char *str, Boolean quoteDollar)
     if (DEBUG(VAR))
-	fprintf(debug_file, "QuoteMeta: [%s]\n", str);
+        fprintf(debug_file, "QuoteMeta: [%s]\n", str);
     return str;
@@ -2378,11 +2409,10 @@ VarQuote(char *str, Boolean quoteDollar)
 static char *
-VarHash(char *str)
-{
-    static const char    hexdigits[16] = "0123456789abcdef";
-    Buffer         buf;
-    size_t         len, len2;
-    unsigned char  *ustr = (unsigned char *)str;
-    unsigned int   h, k, c1, c2;
+VarHash(char *str) {
+    static const char hexdigits[16] = "0123456789abcdef";
+    Buffer buf;
+    size_t len, len2;
+    unsigned char *ustr = (unsigned char *) str;
+    unsigned int h, k, c1, c2;

-    h  = 0x971e137bU;
+    h = 0x971e137bU;
     c1 = 0x95543787U;
@@ -2391,40 +2421,40 @@ VarHash(char *str)

-    for (len = len2; len; ) {
-	k = 0;
-	switch (len) {
-	default:
-	    k = (ustr[3] << 24) | (ustr[2] << 16) | (ustr[1] << 8) | ustr[0];
-	    len -= 4;
-	    ustr += 4;
-	    break;
-	case 3:
-	    k |= (ustr[2] << 16);
-	case 2:
-	    k |= (ustr[1] << 8);
-	case 1:
-	    k |= ustr[0];
-	    len = 0;
-	}
-	c1 = c1 * 5 + 0x7b7d159cU;
-	c2 = c2 * 5 + 0x6bce6396U;
-	k *= c1;
-	k = (k << 11) ^ (k >> 21);
-	k *= c2;
-	h = (h << 13) ^ (h >> 19);
-	h = h * 5 + 0x52dce729U;
-	h ^= k;
-   }
-   h ^= len2;
-   h *= 0x85ebca6b;
-   h ^= h >> 13;
-   h *= 0xc2b2ae35;
-   h ^= h >> 16;
-
-   Buf_Init(&buf, 0);
-   for (len = 0; len < 8; ++len) {
-       Buf_AddByte(&buf, hexdigits[h & 15]);
-       h >>= 4;
-   }
-
-   return Buf_Destroy(&buf, FALSE);
+    for (len = len2; len;) {
+        k = 0;
+        switch (len) {
+            default:
+                k = (ustr[3] << 24) | (ustr[2] << 16) | (ustr[1] << 8) | ustr[0];
+                len -= 4;
+                ustr += 4;
+                break;
+            case 3:
+                k |= (ustr[2] << 16);
+            case 2:
+                k |= (ustr[1] << 8);
+            case 1:
+                k |= ustr[0];
+                len = 0;
+        }
+        c1 = c1 * 5 + 0x7b7d159cU;
+        c2 = c2 * 5 + 0x6bce6396U;
+        k *= c1;
+        k = (k << 11) ^ (k >> 21);
+        k *= c2;
+        h = (h << 13) ^ (h >> 19);
+        h = h * 5 + 0x52dce729U;
+        h ^= k;
+    }
+    h ^= len2;
+    h *= 0x85ebca6b;
+    h ^= h >> 13;
+    h *= 0xc2b2ae35;
+    h ^= h >> 16;
+
+    Buf_Init(&buf, 0);
+    for (len = 0; len < 8; ++len) {
+        Buf_AddByte(&buf, hexdigits[h & 15]);
+        h >>= 4;
+    }
+
+    return Buf_Destroy(&buf, FALSE);
 }
@@ -2432,4 +2462,3 @@ VarHash(char *str)
 static char *
-VarStrftime(const char *fmt, int zulu, time_t utc)
-{
+VarStrftime(const char *fmt, int zulu, time_t utc) {
     char buf[BUFSIZ];
@@ -2437,7 +2466,7 @@ VarStrftime(const char *fmt, int zulu, time_t utc)
     if (!utc)
-	time(&utc);
+        time(&utc);
     if (!*fmt)
-	fmt = "%c";
+        fmt = "%c";
     strftime(buf, sizeof(buf), fmt, zulu ? gmtime(&utc) : localtime(&utc));
-
+
     buf[sizeof(buf) - 1] = '\0';
@@ -2540,18 +2569,29 @@ static char *
 ApplyModifiers(char *nstr, const char *tstr,
-	       int startc, int endc,
-	       Var *v, GNode *ctxt, int flags,
-	       int *lengthPtr, void **freePtr)
-{
-    const char 	   *start;
-    const char     *cp;    	/* Secondary pointer into str (place marker
+               int startc, int endc,
+               Var *v, GNode *ctxt, int flags,
+               int *lengthPtr, void **freePtr) {
+    const char *start;
+    const char *cp;        /* Secondary pointer into str (place marker
 				 * for tstr) */
-    char	   *newStr;	/* New value to return */
-    char	   *ep;
-    char	    termc;	/* Character which terminated scan */
-    int             cnt;	/* Used to count brace pairs when variable in
+#if (defined _WIN32 && ! defined __CYGWIN__)
+    char *unix_nstr;
+    char *error;
+    if (nstr && strlen(nstr) > 0 && nstr[1] == ':' && (nstr[2] == '/' || nstr[2] == '\\')) {
+        unix_nstr = Cmd_Exec(getUnixPathCmd(nstr), &error);
+    }
+    else {
+        unix_nstr = nstr;
+    }
+#else
+    char *unix_nstr = nstr;
+#endif
+    char *newStr;    /* New value to return */
+    char *ep;
+    char termc;    /* Character which terminated scan */
+    int cnt;    /* Used to count brace pairs when variable in
 				 * in parens or braces */
-    char	delim;
-    int		modifier;	/* that we are processing */
+    char delim;
+    int modifier;    /* that we are processing */
     Var_Parse_State parsestate; /* Flags passed to helper functions */
-    time_t	utc;		/* for VarStrftime */
+    time_t utc;        /* for VarStrftime */

@@ -2559,3 +2599,3 @@ ApplyModifiers(char *nstr, const char *tstr,
     parsestate.oneBigWord = FALSE;
-    parsestate.varSpace = ' ';	/* word separator */
+    parsestate.varSpace = ' ';    /* word separator */

@@ -2565,14 +2605,14 @@ ApplyModifiers(char *nstr, const char *tstr,

-	if (*tstr == '$') {
-	    /*
+        if (*tstr == '$') {
+            /*
 	     * We may have some complex modifiers in a variable.
 	     */
-	    void *freeIt;
-	    char *rval;
-	    int rlen;
-	    int c;
+            void *freeIt;
+            char *rval;
+            int rlen;
+            int c;

-	    rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);
+            rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);

-	    /*
+            /*
 	     * If we have not parsed up to endc or ':',
@@ -2580,68 +2620,67 @@ ApplyModifiers(char *nstr, const char *tstr,
 	     */
-	    if (rval != NULL && *rval &&
-		(c = tstr[rlen]) != '\0' &&
-		c != ':' &&
-		c != endc) {
-		free(freeIt);
-		goto apply_mods;
-	    }
-
-	    if (DEBUG(VAR)) {
-		fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n",
-		       rval, rlen, tstr, rlen, tstr + rlen);
-	    }
-
-	    tstr += rlen;
-
-	    if (rval != NULL && *rval) {
-		int used;
-
-		nstr = ApplyModifiers(nstr, rval,
-				      0, 0, v, ctxt, flags, &used, freePtr);
-		if (nstr == var_Error
-		    || (nstr == varNoError && (flags & VARF_UNDEFERR) == 0)
-		    || strlen(rval) != (size_t) used) {
-		    free(freeIt);
-		    goto out;		/* error already reported */
-		}
-	    }
-	    free(freeIt);
-	    if (*tstr == ':')
-		tstr++;
-	    else if (!*tstr && endc) {
-		Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name);
-		goto out;
-	    }
-	    continue;
-	}
-    apply_mods:
-	if (DEBUG(VAR)) {
-	    fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", v->name,
-		*tstr, nstr);
-	}
-	newStr = var_Error;
-	switch ((modifier = *tstr)) {
-	case ':':
-	    {
-		if (tstr[1] == '=' ||
-		    (tstr[2] == '=' &&
-		     (tstr[1] == '!' || tstr[1] == '+' || tstr[1] == '?'))) {
-		    /*
+            if (rval != NULL && *rval &&
+                (c = tstr[rlen]) != '\0' &&
+                c != ':' &&
+                c != endc) {
+                free(freeIt);
+                goto apply_mods;
+            }
+
+            if (DEBUG(VAR)) {
+                fprintf(debug_file, "Got '%s' from '%.*s'%.*s\n",
+                        rval, rlen, tstr, rlen, tstr + rlen);
+            }
+
+            tstr += rlen;
+
+            if (rval != NULL && *rval) {
+                int used;
+
+                unix_nstr = ApplyModifiers(unix_nstr, rval,
+                                      0, 0, v, ctxt, flags, &used, freePtr);
+                if (unix_nstr == var_Error
+                    || (unix_nstr == varNoError && (flags & VARF_UNDEFERR) == 0)
+                    || strlen(rval) != (size_t) used) {
+                    free(freeIt);
+                    goto out;        /* error already reported */
+                }
+            }
+            free(freeIt);
+            if (*tstr == ':')
+                tstr++;
+            else if (!*tstr && endc) {
+                Error("Unclosed variable specification after complex modifier (expecting '%c') for %s", endc, v->name);
+                goto out;
+            }
+            continue;
+        }
+        apply_mods:
+        if (DEBUG(VAR)) {
+            fprintf(debug_file, "Applying[%s] :%c to \"%s\"\n", v->name,
+                    *tstr, unix_nstr);
+        }
+        newStr = var_Error;
+        switch ((modifier = *tstr)) {
+            case ':': {
+                if (tstr[1] == '=' ||
+                    (tstr[2] == '=' &&
+                     (tstr[1] == '!' || tstr[1] == '+' || tstr[1] == '?'))) {
+                    /*
 		     * "::=", "::!=", "::+=", or "::?="
 		     */
-		    GNode *v_ctxt;		/* context where v belongs */
-		    const char *emsg;
-		    char *sv_name;
-		    VarPattern	pattern;
-		    int	how;
-		    int vflags;
-
-		    if (v->name[0] == 0)
-			goto bad_modifier;
-
-		    v_ctxt = ctxt;
-		    sv_name = NULL;
-		    ++tstr;
-		    if (v->flags & VAR_JUNK) {
-			/*
+                    GNode *v_ctxt;        /* context where v belongs */
+                    const char *emsg;
+                    char *sv_name;
+                    VarPattern pattern;
+                    int how;
+                    int vflags;
+
+                    if (v->name[0] == 0)
+                        goto bad_modifier;
+
+                    v_ctxt = ctxt;
+                    sv_name = NULL;
+                    ++tstr;
+                    if (v->flags & VAR_JUNK) {
+                        /*
 			 * We need to bmake_strdup() it incase
@@ -2649,140 +2688,138 @@ ApplyModifiers(char *nstr, const char *tstr,
 			 */
-			sv_name = v->name;
-			v->name = bmake_strdup(v->name);
-		    } else if (ctxt != VAR_GLOBAL) {
-			Var *gv = VarFind(v->name, ctxt, 0);
-			if (gv == NULL)
-			    v_ctxt = VAR_GLOBAL;
-			else
-			    VarFreeEnv(gv, TRUE);
-		    }
-
-		    switch ((how = *tstr)) {
-		    case '+':
-		    case '?':
-		    case '!':
-			cp = &tstr[2];
-			break;
-		    default:
-			cp = ++tstr;
-			break;
-		    }
-		    delim = startc == PROPEN ? PRCLOSE : BRCLOSE;
-		    pattern.flags = 0;
-
-		    vflags = (flags & VARF_WANTRES) ? 0 : VAR_NOSUBST;
-		    pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
-						&cp, delim, &vflags,
-						&pattern.rightLen,
-						NULL);
-		    if (v->flags & VAR_JUNK) {
-			/* restore original name */
-			free(v->name);
-			v->name = sv_name;
-		    }
-		    if (pattern.rhs == NULL)
-			goto cleanup;
-
-		    termc = *--cp;
-		    delim = '\0';
-
-		    if (flags & VARF_WANTRES) {
-			switch (how) {
-			case '+':
-			    Var_Append(v->name, pattern.rhs, v_ctxt);
-			    break;
-			case '!':
-			    newStr = Cmd_Exec(pattern.rhs, &emsg);
-			    if (emsg)
-				Error(emsg, nstr);
-			    else
-				Var_Set(v->name, newStr,  v_ctxt, 0);
-			    free(newStr);
-			    break;
-			case '?':
-			    if ((v->flags & VAR_JUNK) == 0)
-				break;
-			    /* FALLTHROUGH */
-			default:
-			    Var_Set(v->name, pattern.rhs, v_ctxt, 0);
-			    break;
-			}
-		    }
-		    free(UNCONST(pattern.rhs));
-		    newStr = varNoError;
-		    break;
-		}
-		goto default_case; /* "::<unrecognised>" */
-	    }
-	case '@':
-	    {
-		VarLoop_t	loop;
-		int vflags = VAR_NOSUBST;
-
-		cp = ++tstr;
-		delim = '@';
-		if ((loop.tvar = VarGetPattern(ctxt, &parsestate, flags,
-					       &cp, delim,
-					       &vflags, &loop.tvarLen,
-					       NULL)) == NULL)
-		    goto cleanup;
-
-		if ((loop.str = VarGetPattern(ctxt, &parsestate, flags,
-					      &cp, delim,
-					      &vflags, &loop.strLen,
-					      NULL)) == NULL)
-		    goto cleanup;
-
-		termc = *cp;
-		delim = '\0';
-
-		loop.errnum = flags & VARF_UNDEFERR;
-		loop.ctxt = ctxt;
-		newStr = VarModify(ctxt, &parsestate, nstr, VarLoopExpand,
-				   &loop);
-		Var_Delete(loop.tvar, ctxt);
-		free(loop.tvar);
-		free(loop.str);
-		break;
-	    }
-	case '_':			/* remember current value */
-	    cp = tstr + 1;	/* make sure it is set */
-	    if (STRMOD_MATCHX(tstr, "_", 1)) {
-		if (tstr[1] == '=') {
-		    char *np;
-		    int n;
-
-		    cp++;
-		    n = strcspn(cp, ":)}");
-		    np = bmake_strndup(cp, n+1);
-		    np[n] = '\0';
-		    cp = tstr + 2 + n;
-		    Var_Set(np, nstr, ctxt, 0);
-		    free(np);
-		} else {
-		    Var_Set("_", nstr, ctxt, 0);
-		}
-		newStr = nstr;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
-	case 'D':
-	case 'U':
-	    {
-		Buffer  buf;    	/* Buffer for patterns */
-		int	nflags;
-
-		if (flags & VARF_WANTRES) {
-		    int wantres;
-		    if (*tstr == 'U')
-			wantres = ((v->flags & VAR_JUNK) != 0);
-		    else
-			wantres = ((v->flags & VAR_JUNK) == 0);
-		    nflags = flags & ~VARF_WANTRES;
-		    if (wantres)
-			nflags |= VARF_WANTRES;
-		} else
-		    nflags = flags;
-		/*
+                        sv_name = v->name;
+                        v->name = bmake_strdup(v->name);
+                    } else if (ctxt != VAR_GLOBAL) {
+                        Var *gv = VarFind(v->name, ctxt, 0);
+                        if (gv == NULL)
+                            v_ctxt = VAR_GLOBAL;
+                        else
+                            VarFreeEnv(gv, TRUE);
+                    }
+
+                    switch ((how = *tstr)) {
+                        case '+':
+                        case '?':
+                        case '!':
+                            cp = &tstr[2];
+                            break;
+                        default:
+                            cp = ++tstr;
+                            break;
+                    }
+                    delim = startc == PROPEN ? PRCLOSE : BRCLOSE;
+                    pattern.flags = 0;
+
+                    vflags = (flags & VARF_WANTRES) ? 0 : VAR_NOSUBST;
+                    pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
+                                                &cp, delim, &vflags,
+                                                &pattern.rightLen,
+                                                NULL);
+                    if (v->flags & VAR_JUNK) {
+                        /* restore original name */
+                        free(v->name);
+                        v->name = sv_name;
+                    }
+                    if (pattern.rhs == NULL)
+                        goto cleanup;
+
+                    termc = *--cp;
+                    delim = '\0';
+
+                    if (flags & VARF_WANTRES) {
+                        switch (how) {
+                            case '+':
+                                Var_Append(v->name, pattern.rhs, v_ctxt);
+                                break;
+                            case '!':
+                                newStr = Cmd_Exec(pattern.rhs, &emsg);
+                                if (emsg)
+                                    Error(emsg, unix_nstr);
+                                else
+                                    Var_Set(v->name, newStr, v_ctxt, 0);
+                                free(newStr);
+                                break;
+                            case '?':
+                                if ((v->flags & VAR_JUNK) == 0)
+                                    break;
+                                /* FALLTHROUGH */
+                            default:
+                                Var_Set(v->name, pattern.rhs, v_ctxt, 0);
+                                break;
+                        }
+                    }
+                    free(UNCONST(pattern.rhs));
+                    newStr = varNoError;
+                    break;
+                }
+                goto default_case; /* "::<unrecognised>" */
+            }
+            case '@': {
+                VarLoop_t loop;
+                int vflags = VAR_NOSUBST;
+
+                cp = ++tstr;
+                delim = '@';
+                if ((loop.tvar = VarGetPattern(ctxt, &parsestate, flags,
+                                               &cp, delim,
+                                               &vflags, &loop.tvarLen,
+                                               NULL)) == NULL)
+                    goto cleanup;
+
+                if ((loop.str = VarGetPattern(ctxt, &parsestate, flags,
+                                              &cp, delim,
+                                              &vflags, &loop.strLen,
+                                              NULL)) == NULL)
+                    goto cleanup;
+
+                termc = *cp;
+                delim = '\0';
+
+                loop.errnum = flags & VARF_UNDEFERR;
+                loop.ctxt = ctxt;
+                newStr = VarModify(ctxt, &parsestate, unix_nstr, VarLoopExpand,
+                                   &loop);
+                Var_Delete(loop.tvar, ctxt);
+                free(loop.tvar);
+                free(loop.str);
+                break;
+            }
+            case '_':            /* remember current value */
+                cp = tstr + 1;    /* make sure it is set */
+                if (STRMOD_MATCHX(tstr, "_", 1)) {
+                    if (tstr[1] == '=') {
+                        char *np;
+                        int n;
+
+                        cp++;
+                        n = strcspn(cp, ":)}");
+                        np = bmake_strndup(cp, n + 1);
+                        np[n] = '\0';
+                        cp = tstr + 2 + n;
+                        Var_Set(np, unix_nstr, ctxt, 0);
+                        free(np);
+                    } else {
+                        Var_Set("_", unix_nstr, ctxt, 0);
+                    }
+                    newStr = unix_nstr;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
+            case 'D':
+            case 'U': {
+                Buffer buf;        /* Buffer for patterns */
+                int nflags;
+
+                if (flags & VARF_WANTRES) {
+                    int wantres;
+                    if (*tstr == 'U')
+                        wantres = ((v->flags & VAR_JUNK) != 0);
+                    else
+                        wantres = ((v->flags & VAR_JUNK) == 0);
+                    nflags = flags & ~VARF_WANTRES;
+                    if (wantres)
+                        nflags |= VARF_WANTRES;
+                } else
+                    nflags = flags;
+                /*
 		 * Pass through tstr looking for 1) escaped delimiters,
@@ -2793,16 +2830,15 @@ ApplyModifiers(char *nstr, const char *tstr,
 		 */
-		Buf_Init(&buf, 0);
-		for (cp = tstr + 1;
-		     *cp != endc && *cp != ':' && *cp != '\0';
-		     cp++) {
-		    if ((*cp == '\\') &&
-			((cp[1] == ':') ||
-			 (cp[1] == '$') ||
-			 (cp[1] == endc) ||
-			 (cp[1] == '\\')))
-			{
-			    Buf_AddByte(&buf, cp[1]);
-			    cp++;
-			} else if (*cp == '$') {
-			    /*
+                Buf_Init(&buf, 0);
+                for (cp = tstr + 1;
+                     *cp != endc && *cp != ':' && *cp != '\0';
+                     cp++) {
+                    if ((*cp == '\\') &&
+                        ((cp[1] == ':') ||
+                         (cp[1] == '$') ||
+                         (cp[1] == endc) ||
+                         (cp[1] == '\\'))) {
+                        Buf_AddByte(&buf, cp[1]);
+                        cp++;
+                    } else if (*cp == '$') {
+                        /*
 			     * If unescaped dollar sign, assume it's a
@@ -2810,88 +2846,84 @@ ApplyModifiers(char *nstr, const char *tstr,
 			     */
-			    char    *cp2;
-			    int	    len;
-			    void    *freeIt;
-
-			    cp2 = Var_Parse(cp, ctxt, nflags, &len, &freeIt);
-			    Buf_AddBytes(&buf, strlen(cp2), cp2);
-			    free(freeIt);
-			    cp += len - 1;
-			} else {
-			    Buf_AddByte(&buf, *cp);
-			}
-		}
-
-		termc = *cp;
-
-		if ((v->flags & VAR_JUNK) != 0)
-		    v->flags |= VAR_KEEP;
-		if (nflags & VARF_WANTRES) {
-		    newStr = Buf_Destroy(&buf, FALSE);
-		} else {
-		    newStr = nstr;
-		    Buf_Destroy(&buf, TRUE);
-		}
-		break;
-	    }
-	case 'L':
-	    {
-		if ((v->flags & VAR_JUNK) != 0)
-		    v->flags |= VAR_KEEP;
-		newStr = bmake_strdup(v->name);
-		cp = ++tstr;
-		termc = *tstr;
-		break;
-	    }
-	case 'P':
-	    {
-		GNode *gn;
-
-		if ((v->flags & VAR_JUNK) != 0)
-		    v->flags |= VAR_KEEP;
-		gn = Targ_FindNode(v->name, TARG_NOCREATE);
-		if (gn == NULL || gn->type & OP_NOPATH) {
-		    newStr = NULL;
-		} else if (gn->path) {
-		    newStr = bmake_strdup(gn->path);
-		} else {
-		    newStr = Dir_FindFile(v->name, Suff_FindPath(gn));
-		}
-		if (!newStr) {
-		    newStr = bmake_strdup(v->name);
-		}
-		cp = ++tstr;
-		termc = *tstr;
-		break;
-	    }
-	case '!':
-	    {
-		const char *emsg;
-		VarPattern 	    pattern;
-		pattern.flags = 0;
-
-		delim = '!';
-		emsg = NULL;
-		cp = ++tstr;
-		if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
-						 &cp, delim,
-						 NULL, &pattern.rightLen,
-						 NULL)) == NULL)
-		    goto cleanup;
-		if (flags & VARF_WANTRES)
-		    newStr = Cmd_Exec(pattern.rhs, &emsg);
-		else
-		    newStr = varNoError;
-		free(UNCONST(pattern.rhs));
-		if (emsg)
-		    Error(emsg, nstr);
-		termc = *cp;
-		delim = '\0';
-		if (v->flags & VAR_JUNK) {
-		    v->flags |= VAR_KEEP;
-		}
-		break;
-	    }
-	case '[':
-	    {
-		/*
+                        char *cp2;
+                        int len;
+                        void *freeIt;
+
+                        cp2 = Var_Parse(cp, ctxt, nflags, &len, &freeIt);
+                        Buf_AddBytes(&buf, strlen(cp2), cp2);
+                        free(freeIt);
+                        cp += len - 1;
+                    } else {
+                        Buf_AddByte(&buf, *cp);
+                    }
+                }
+
+                termc = *cp;
+
+                if ((v->flags & VAR_JUNK) != 0)
+                    v->flags |= VAR_KEEP;
+                if (nflags & VARF_WANTRES) {
+                    newStr = Buf_Destroy(&buf, FALSE);
+                } else {
+                    newStr = unix_nstr;
+                    Buf_Destroy(&buf, TRUE);
+                }
+                break;
+            }
+            case 'L': {
+                if ((v->flags & VAR_JUNK) != 0)
+                    v->flags |= VAR_KEEP;
+                newStr = bmake_strdup(v->name);
+                cp = ++tstr;
+                termc = *tstr;
+                break;
+            }
+            case 'P': {
+                GNode *gn;
+
+                if ((v->flags & VAR_JUNK) != 0)
+                    v->flags |= VAR_KEEP;
+                gn = Targ_FindNode(v->name, TARG_NOCREATE);
+                if (gn == NULL || gn->type & OP_NOPATH) {
+                    newStr = NULL;
+                } else if (gn->path) {
+                    newStr = bmake_strdup(gn->path);
+                } else {
+                    newStr = Dir_FindFile(v->name, Suff_FindPath(gn));
+                }
+                if (!newStr) {
+                    newStr = bmake_strdup(v->name);
+                }
+                cp = ++tstr;
+                termc = *tstr;
+                break;
+            }
+            case '!': {
+                const char *emsg;
+                VarPattern pattern;
+                pattern.flags = 0;
+
+                delim = '!';
+                emsg = NULL;
+                cp = ++tstr;
+                if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
+                                                 &cp, delim,
+                                                 NULL, &pattern.rightLen,
+                                                 NULL)) == NULL)
+                    goto cleanup;
+                if (flags & VARF_WANTRES)
+                    newStr = Cmd_Exec(pattern.rhs, &emsg);
+                else
+                    newStr = varNoError;
+                free(UNCONST(pattern.rhs));
+                if (emsg)
+                    Error(emsg, unix_nstr);
+                termc = *cp;
+                delim = '\0';
+                if (v->flags & VAR_JUNK) {
+                    v->flags |= VAR_KEEP;
+                }
+                break;
+            }
+            case '[': {
+                /*
 		 * Look for the closing ']', recursively
@@ -2902,26 +2934,26 @@ ApplyModifiers(char *nstr, const char *tstr,
 		 */
-		char *estr;
-
-		cp = tstr+1; /* point to char after '[' */
-		delim = ']'; /* look for closing ']' */
-		estr = VarGetPattern(ctxt, &parsestate,
-				     flags, &cp, delim,
-				     NULL, NULL, NULL);
-		if (estr == NULL)
-		    goto cleanup; /* report missing ']' */
-		/* now cp points just after the closing ']' */
-		delim = '\0';
-		if (cp[0] != ':' && cp[0] != endc) {
-		    /* Found junk after ']' */
-		    free(estr);
-		    goto bad_modifier;
-		}
-		if (estr[0] == '\0') {
-		    /* Found empty square brackets in ":[]". */
-		    free(estr);
-		    goto bad_modifier;
-		} else if (estr[0] == '#' && estr[1] == '\0') {
-		    /* Found ":[#]" */
-
-		    /*
+                char *estr;
+
+                cp = tstr + 1; /* point to char after '[' */
+                delim = ']'; /* look for closing ']' */
+                estr = VarGetPattern(ctxt, &parsestate,
+                                     flags, &cp, delim,
+                                     NULL, NULL, NULL);
+                if (estr == NULL)
+                    goto cleanup; /* report missing ']' */
+                /* now cp points just after the closing ']' */
+                delim = '\0';
+                if (cp[0] != ':' && cp[0] != endc) {
+                    /* Found junk after ']' */
+                    free(estr);
+                    goto bad_modifier;
+                }
+                if (estr[0] == '\0') {
+                    /* Found empty square brackets in ":[]". */
+                    free(estr);
+                    goto bad_modifier;
+                } else if (estr[0] == '#' && estr[1] == '\0') {
+                    /* Found ":[#]" */
+
+                    /*
 		     * We will need enough space for the decimal
@@ -2933,39 +2965,39 @@ ApplyModifiers(char *nstr, const char *tstr,
 		     */
-		    int newStrSize =
-			(sizeof(int) * CHAR_BIT + 2) / 3 + 2;
-
-		    newStr = bmake_malloc(newStrSize);
-		    if (parsestate.oneBigWord) {
-			strncpy(newStr, "1", newStrSize);
-		    } else {
-			/* XXX: brk_string() is a rather expensive
+                    int newStrSize =
+                            (sizeof(int) * CHAR_BIT + 2) / 3 + 2;
+
+                    newStr = bmake_malloc(newStrSize);
+                    if (parsestate.oneBigWord) {
+                        strncpy(newStr, "1", newStrSize);
+                    } else {
+                        /* XXX: brk_string() is a rather expensive
 			 * way of counting words. */
-			char **av;
-			char *as;
-			int ac;
-
-			av = brk_string(nstr, &ac, FALSE, &as);
-			snprintf(newStr, newStrSize,  "%d", ac);
-			free(as);
-			free(av);
-		    }
-		    termc = *cp;
-		    free(estr);
-		    break;
-		} else if (estr[0] == '*' && estr[1] == '\0') {
-		    /* Found ":[*]" */
-		    parsestate.oneBigWord = TRUE;
-		    newStr = nstr;
-		    termc = *cp;
-		    free(estr);
-		    break;
-		} else if (estr[0] == '@' && estr[1] == '\0') {
-		    /* Found ":[@]" */
-		    parsestate.oneBigWord = FALSE;
-		    newStr = nstr;
-		    termc = *cp;
-		    free(estr);
-		    break;
-		} else {
-		    /*
+                        char **av;
+                        char *as;
+                        int ac;
+
+                        av = brk_string(unix_nstr, &ac, FALSE, &as);
+                        snprintf(newStr, newStrSize, "%d", ac);
+                        free(as);
+                        free(av);
+                    }
+                    termc = *cp;
+                    free(estr);
+                    break;
+                } else if (estr[0] == '*' && estr[1] == '\0') {
+                    /* Found ":[*]" */
+                    parsestate.oneBigWord = TRUE;
+                    newStr = unix_nstr;
+                    termc = *cp;
+                    free(estr);
+                    break;
+                } else if (estr[0] == '@' && estr[1] == '\0') {
+                    /* Found ":[@]" */
+                    parsestate.oneBigWord = FALSE;
+                    newStr = unix_nstr;
+                    termc = *cp;
+                    free(estr);
+                    break;
+                } else {
+                    /*
 		     * We expect estr to contain a single
@@ -2974,28 +3006,28 @@ ApplyModifiers(char *nstr, const char *tstr,
 		     */
-		    VarSelectWords_t seldata = { 0, 0 };
-
-		    seldata.start = strtol(estr, &ep, 0);
-		    if (ep == estr) {
-			/* Found junk instead of a number */
-			free(estr);
-			goto bad_modifier;
-		    } else if (ep[0] == '\0') {
-			/* Found only one integer in :[N] */
-			seldata.end = seldata.start;
-		    } else if (ep[0] == '.' && ep[1] == '.' &&
-			       ep[2] != '\0') {
-			/* Expecting another integer after ".." */
-			ep += 2;
-			seldata.end = strtol(ep, &ep, 0);
-			if (ep[0] != '\0') {
-			    /* Found junk after ".." */
-			    free(estr);
-			    goto bad_modifier;
-			}
-		    } else {
-			/* Found junk instead of ".." */
-			free(estr);
-			goto bad_modifier;
-		    }
-		    /*
+                    VarSelectWords_t seldata = {0, 0};
+
+                    seldata.start = strtol(estr, &ep, 0);
+                    if (ep == estr) {
+                        /* Found junk instead of a number */
+                        free(estr);
+                        goto bad_modifier;
+                    } else if (ep[0] == '\0') {
+                        /* Found only one integer in :[N] */
+                        seldata.end = seldata.start;
+                    } else if (ep[0] == '.' && ep[1] == '.' &&
+                               ep[2] != '\0') {
+                        /* Expecting another integer after ".." */
+                        ep += 2;
+                        seldata.end = strtol(ep, &ep, 0);
+                        if (ep[0] != '\0') {
+                            /* Found junk after ".." */
+                            free(estr);
+                            goto bad_modifier;
+                        }
+                    } else {
+                        /* Found junk instead of ".." */
+                        free(estr);
+                        goto bad_modifier;
+                    }
+                    /*
 		     * Now seldata is properly filled in,
@@ -3004,16 +3036,16 @@ ApplyModifiers(char *nstr, const char *tstr,
 		     */
-		    if (seldata.start == 0 && seldata.end == 0) {
-			/* ":[0]" or perhaps ":[0..0]" */
-			parsestate.oneBigWord = TRUE;
-			newStr = nstr;
-			termc = *cp;
-			free(estr);
-			break;
-		    } else if (seldata.start == 0 ||
-			       seldata.end == 0) {
-			/* ":[0..N]" or ":[N..0]" */
-			free(estr);
-			goto bad_modifier;
-		    }
-		    /*
+                    if (seldata.start == 0 && seldata.end == 0) {
+                        /* ":[0]" or perhaps ":[0..0]" */
+                        parsestate.oneBigWord = TRUE;
+                        newStr = unix_nstr;
+                        termc = *cp;
+                        free(estr);
+                        break;
+                    } else if (seldata.start == 0 ||
+                               seldata.end == 0) {
+                        /* ":[0..N]" or ":[N..0]" */
+                        free(estr);
+                        goto bad_modifier;
+                    }
+                    /*
 		     * Normal case: select the words
@@ -3021,59 +3053,58 @@ ApplyModifiers(char *nstr, const char *tstr,
 		     */
-		    newStr = VarSelectWords(ctxt, &parsestate,
-					    nstr, &seldata);
-
-		    termc = *cp;
-		    free(estr);
-		    break;
-		}
-
-	    }
-	case 'g':
-	    cp = tstr + 1;	/* make sure it is set */
-	    if (STRMOD_MATCHX(tstr, "gmtime", 6)) {
-		if (tstr[6] == '=') {
-		    utc = strtoul(&tstr[7], &ep, 10);
-		    cp = ep;
-		} else {
-		    utc = 0;
-		    cp = tstr + 6;
-		}
-		newStr = VarStrftime(nstr, 1, utc);
-		termc = *cp;
-	    } else {
-		goto default_case;
-	    }
-	    break;
-	case 'h':
-	    cp = tstr + 1;	/* make sure it is set */
-	    if (STRMOD_MATCH(tstr, "hash", 4)) {
-		newStr = VarHash(nstr);
-		cp = tstr + 4;
-		termc = *cp;
-	    } else {
-		goto default_case;
-	    }
-	    break;
-	case 'l':
-	    cp = tstr + 1;	/* make sure it is set */
-	    if (STRMOD_MATCHX(tstr, "localtime", 9)) {
-		if (tstr[9] == '=') {
-		    utc = strtoul(&tstr[10], &ep, 10);
-		    cp = ep;
-		} else {
-		    utc = 0;
-		    cp = tstr + 9;
-		}
-		newStr = VarStrftime(nstr, 0, utc);
-		termc = *cp;
-	    } else {
-		goto default_case;
-	    }
-	    break;
-	case 't':
-	    {
-		cp = tstr + 1;	/* make sure it is set */
-		if (tstr[1] != endc && tstr[1] != ':') {
-		    if (tstr[1] == 's') {
-			/*
+                    newStr = VarSelectWords(ctxt, &parsestate,
+                                            unix_nstr, &seldata);
+
+                    termc = *cp;
+                    free(estr);
+                    break;
+                }
+
+            }
+            case 'g':
+                cp = tstr + 1;    /* make sure it is set */
+                if (STRMOD_MATCHX(tstr, "gmtime", 6)) {
+                    if (tstr[6] == '=') {
+                        utc = strtoul(&tstr[7], &ep, 10);
+                        cp = ep;
+                    } else {
+                        utc = 0;
+                        cp = tstr + 6;
+                    }
+                    newStr = VarStrftime(unix_nstr, 1, utc);
+                    termc = *cp;
+                } else {
+                    goto default_case;
+                }
+                break;
+            case 'h':
+                cp = tstr + 1;    /* make sure it is set */
+                if (STRMOD_MATCH(tstr, "hash", 4)) {
+                    newStr = VarHash(unix_nstr);
+                    cp = tstr + 4;
+                    termc = *cp;
+                } else {
+                    goto default_case;
+                }
+                break;
+            case 'l':
+                cp = tstr + 1;    /* make sure it is set */
+                if (STRMOD_MATCHX(tstr, "localtime", 9)) {
+                    if (tstr[9] == '=') {
+                        utc = strtoul(&tstr[10], &ep, 10);
+                        cp = ep;
+                    } else {
+                        utc = 0;
+                        cp = tstr + 9;
+                    }
+                    newStr = VarStrftime(unix_nstr, 0, utc);
+                    termc = *cp;
+                } else {
+                    goto default_case;
+                }
+                break;
+            case 't': {
+                cp = tstr + 1;    /* make sure it is set */
+                if (tstr[1] != endc && tstr[1] != ':') {
+                    if (tstr[1] == 's') {
+                        /*
 			 * Use the char (if any) at tstr[2]
@@ -3081,61 +3112,61 @@ ApplyModifiers(char *nstr, const char *tstr,
 			 */
-			VarPattern pattern;
+                        VarPattern pattern;

-			if (tstr[2] != endc &&
-			    (tstr[3] == endc || tstr[3] == ':')) {
-			    /* ":ts<unrecognised><endc>" or
+                        if (tstr[2] != endc &&
+                            (tstr[3] == endc || tstr[3] == ':')) {
+                            /* ":ts<unrecognised><endc>" or
 			     * ":ts<unrecognised>:" */
-			    parsestate.varSpace = tstr[2];
-			    cp = tstr + 3;
-			} else if (tstr[2] == endc || tstr[2] == ':') {
-			    /* ":ts<endc>" or ":ts:" */
-			    parsestate.varSpace = 0; /* no separator */
-			    cp = tstr + 2;
-			} else if (tstr[2] == '\\') {
-			    const char *xp = &tstr[3];
-			    int base = 8; /* assume octal */
-
-			    switch (tstr[3]) {
-			    case 'n':
-				parsestate.varSpace = '\n';
-				cp = tstr + 4;
-				break;
-			    case 't':
-				parsestate.varSpace = '\t';
-				cp = tstr + 4;
-				break;
-			    case 'x':
-				base = 16;
-				xp++;
-				goto get_numeric;
-			    case '0':
-				base = 0;
-				goto get_numeric;
-			    default:
-				if (isdigit((unsigned char)tstr[3])) {
-
-				get_numeric:
-				    parsestate.varSpace =
-					strtoul(xp, &ep, base);
-				    if (*ep != ':' && *ep != endc)
-					goto bad_modifier;
-				    cp = ep;
-				} else {
-				    /*
+                            parsestate.varSpace = tstr[2];
+                            cp = tstr + 3;
+                        } else if (tstr[2] == endc || tstr[2] == ':') {
+                            /* ":ts<endc>" or ":ts:" */
+                            parsestate.varSpace = 0; /* no separator */
+                            cp = tstr + 2;
+                        } else if (tstr[2] == '\\') {
+                            const char *xp = &tstr[3];
+                            int base = 8; /* assume octal */
+
+                            switch (tstr[3]) {
+                                case 'n':
+                                    parsestate.varSpace = '\n';
+                                    cp = tstr + 4;
+                                    break;
+                                case 't':
+                                    parsestate.varSpace = '\t';
+                                    cp = tstr + 4;
+                                    break;
+                                case 'x':
+                                    base = 16;
+                                    xp++;
+                                    goto get_numeric;
+                                case '0':
+                                    base = 0;
+                                    goto get_numeric;
+                                default:
+                                    if (isdigit((unsigned char) tstr[3])) {
+
+                                        get_numeric:
+                                        parsestate.varSpace =
+                                                strtoul(xp, &ep, base);
+                                        if (*ep != ':' && *ep != endc)
+                                            goto bad_modifier;
+                                        cp = ep;
+                                    } else {
+                                        /*
 				     * ":ts<backslash><unrecognised>".
 				     */
-				    goto bad_modifier;
-				}
-				break;
-			    }
-			} else {
-			    /*
+                                        goto bad_modifier;
+                                    }
+                                    break;
+                            }
+                        } else {
+                            /*
 			     * Found ":ts<unrecognised><unrecognised>".
 			     */
-			    goto bad_modifier;
-			}
+                            goto bad_modifier;
+                        }

-			termc = *cp;
+                        termc = *cp;

-			/*
+                        /*
 			 * We cannot be certain that VarModify
@@ -3146,11 +3177,11 @@ ApplyModifiers(char *nstr, const char *tstr,
 			 */
-			pattern.flags = VAR_SUB_ONE;
-			pattern.lhs = pattern.rhs = "\032";
-			pattern.leftLen = pattern.rightLen = 1;
-
-			newStr = VarModify(ctxt, &parsestate, nstr,
-					   VarSubstitute,
-					   &pattern);
-		    } else if (tstr[2] == endc || tstr[2] == ':') {
-			/*
+                        pattern.flags = VAR_SUB_ONE;
+                        pattern.lhs = pattern.rhs = "\032";
+                        pattern.leftLen = pattern.rightLen = 1;
+
+                        newStr = VarModify(ctxt, &parsestate, unix_nstr,
+                                           VarSubstitute,
+                                           &pattern);
+                    } else if (tstr[2] == endc || tstr[2] == ':') {
+                        /*
 			 * Check for two-character options:
@@ -3158,57 +3189,56 @@ ApplyModifiers(char *nstr, const char *tstr,
 			 */
-			if (tstr[1] == 'A') { /* absolute path */
-			    newStr = VarModify(ctxt, &parsestate, nstr,
-					       VarRealpath, NULL);
-			    cp = tstr + 2;
-			    termc = *cp;
-			} else if (tstr[1] == 'u') {
-			    char *dp = bmake_strdup(nstr);
-			    for (newStr = dp; *dp; dp++)
-				*dp = toupper((unsigned char)*dp);
-			    cp = tstr + 2;
-			    termc = *cp;
-			} else if (tstr[1] == 'l') {
-			    char *dp = bmake_strdup(nstr);
-			    for (newStr = dp; *dp; dp++)
-				*dp = tolower((unsigned char)*dp);
-			    cp = tstr + 2;
-			    termc = *cp;
-			} else if (tstr[1] == 'W' || tstr[1] == 'w') {
-			    parsestate.oneBigWord = (tstr[1] == 'W');
-			    newStr = nstr;
-			    cp = tstr + 2;
-			    termc = *cp;
-			} else {
-			    /* Found ":t<unrecognised>:" or
+                        if (tstr[1] == 'A') { /* absolute path */
+                            newStr = VarModify(ctxt, &parsestate, unix_nstr,
+                                               VarRealpath, NULL);
+                            cp = tstr + 2;
+                            termc = *cp;
+                        } else if (tstr[1] == 'u') {
+                            char *dp = bmake_strdup(unix_nstr);
+                            for (newStr = dp; *dp; dp++)
+                                *dp = toupper((unsigned char) *dp);
+                            cp = tstr + 2;
+                            termc = *cp;
+                        } else if (tstr[1] == 'l') {
+                            char *dp = bmake_strdup(unix_nstr);
+                            for (newStr = dp; *dp; dp++)
+                                *dp = tolower((unsigned char) *dp);
+                            cp = tstr + 2;
+                            termc = *cp;
+                        } else if (tstr[1] == 'W' || tstr[1] == 'w') {
+                            parsestate.oneBigWord = (tstr[1] == 'W');
+                            newStr = unix_nstr;
+                            cp = tstr + 2;
+                            termc = *cp;
+                        } else {
+                            /* Found ":t<unrecognised>:" or
 			     * ":t<unrecognised><endc>". */
-			    goto bad_modifier;
-			}
-		    } else {
-			/*
+                            goto bad_modifier;
+                        }
+                    } else {
+                        /*
 			 * Found ":t<unrecognised><unrecognised>".
 			 */
-			goto bad_modifier;
-		    }
-		} else {
-		    /*
+                        goto bad_modifier;
+                    }
+                } else {
+                    /*
 		     * Found ":t<endc>" or ":t:".
 		     */
-		    goto bad_modifier;
-		}
-		break;
-	    }
-	case 'N':
-	case 'M':
-	    {
-		char    *pattern;
-		const char *endpat; /* points just after end of pattern */
-		char    *cp2;
-		Boolean copy;	/* pattern should be, or has been, copied */
-		Boolean needSubst;
-		int nest;
-
-		copy = FALSE;
-		needSubst = FALSE;
-		nest = 1;
-		/*
+                    goto bad_modifier;
+                }
+                break;
+            }
+            case 'N':
+            case 'M': {
+                char *pattern;
+                const char *endpat; /* points just after end of pattern */
+                char *cp2;
+                Boolean copy;    /* pattern should be, or has been, copied */
+                Boolean needSubst;
+                int nest;
+
+                copy = FALSE;
+                needSubst = FALSE;
+                nest = 1;
+                /*
 		 * In the loop below, ignore ':' unless we are at
@@ -3218,30 +3248,29 @@ ApplyModifiers(char *nstr, const char *tstr,
 		 */
-		for (cp = tstr + 1;
-		     *cp != '\0' && !(*cp == ':' && nest == 1);
-		     cp++)
-		    {
-			if (*cp == '\\' &&
-			    (cp[1] == ':' ||
-			     cp[1] == endc || cp[1] == startc)) {
-			    if (!needSubst) {
-				copy = TRUE;
-			    }
-			    cp++;
-			    continue;
-			}
-			if (*cp == '$') {
-			    needSubst = TRUE;
-			}
-			if (*cp == '(' || *cp == '{')
-			    ++nest;
-			if (*cp == ')' || *cp == '}') {
-			    --nest;
-			    if (nest == 0)
-				break;
-			}
-		    }
-		termc = *cp;
-		endpat = cp;
-		if (copy) {
-		    /*
+                for (cp = tstr + 1;
+                     *cp != '\0' && !(*cp == ':' && nest == 1);
+                     cp++) {
+                    if (*cp == '\\' &&
+                        (cp[1] == ':' ||
+                         cp[1] == endc || cp[1] == startc)) {
+                        if (!needSubst) {
+                            copy = TRUE;
+                        }
+                        cp++;
+                        continue;
+                    }
+                    if (*cp == '$') {
+                        needSubst = TRUE;
+                    }
+                    if (*cp == '(' || *cp == '{')
+                        ++nest;
+                    if (*cp == ')' || *cp == '}') {
+                        --nest;
+                        if (nest == 0)
+                            break;
+                    }
+                }
+                termc = *cp;
+                endpat = cp;
+                if (copy) {
+                    /*
 		     * Need to compress the \:'s out of the pattern, so
@@ -3252,17 +3281,16 @@ ApplyModifiers(char *nstr, const char *tstr,
 		     */
-		    pattern = bmake_malloc(cp - tstr);
-		    for (cp2 = pattern, cp = tstr + 1;
-			 cp < endpat;
-			 cp++, cp2++)
-			{
-			    if ((*cp == '\\') && (cp+1 < endpat) &&
-				(cp[1] == ':' || cp[1] == endc)) {
-				cp++;
-			    }
-			    *cp2 = *cp;
-			}
-		    *cp2 = '\0';
-		    endpat = cp2;
-		} else {
-		    /*
+                    pattern = bmake_malloc(cp - tstr);
+                    for (cp2 = pattern, cp = tstr + 1;
+                         cp < endpat;
+                         cp++, cp2++) {
+                        if ((*cp == '\\') && (cp + 1 < endpat) &&
+                            (cp[1] == ':' || cp[1] == endc)) {
+                            cp++;
+                        }
+                        *cp2 = *cp;
+                    }
+                    *cp2 = '\0';
+                    endpat = cp2;
+                } else {
+                    /*
 		     * Either Var_Subst or VarModify will need a
@@ -3270,6 +3298,6 @@ ApplyModifiers(char *nstr, const char *tstr,
 		     */
-		    pattern = bmake_strndup(tstr+1, endpat - (tstr + 1));
-		}
-		if (needSubst) {
-		    /*
+                    pattern = bmake_strndup(tstr + 1, endpat - (tstr + 1));
+                }
+                if (needSubst) {
+                    /*
 		     * pattern contains embedded '$', so use Var_Subst to
@@ -3277,30 +3305,29 @@ ApplyModifiers(char *nstr, const char *tstr,
 		     */
-		    cp2 = pattern;
-		    pattern = Var_Subst(NULL, cp2, ctxt, flags | VARF_WANTRES);
-		    free(cp2);
-		}
-		if (DEBUG(VAR))
-		    fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n",
-			v->name, nstr, pattern);
-		if (*tstr == 'M') {
-		    newStr = VarModify(ctxt, &parsestate, nstr, VarMatch,
-				       pattern);
-		} else {
-		    newStr = VarModify(ctxt, &parsestate, nstr, VarNoMatch,
-				       pattern);
-		}
-		free(pattern);
-		break;
-	    }
-	case 'S':
-	    {
-		VarPattern 	    pattern;
-		Var_Parse_State tmpparsestate;
-
-		pattern.flags = 0;
-		tmpparsestate = parsestate;
-		delim = tstr[1];
-		tstr += 2;
-
-		/*
+                    cp2 = pattern;
+                    pattern = Var_Subst(NULL, cp2, ctxt, flags | VARF_WANTRES);
+                    free(cp2);
+                }
+                if (DEBUG(VAR))
+                    fprintf(debug_file, "Pattern[%s] for [%s] is [%s]\n",
+                            v->name, unix_nstr, pattern);
+                if (*tstr == 'M') {
+                    newStr = VarModify(ctxt, &parsestate, unix_nstr, VarMatch,
+                                       pattern);
+                } else {
+                    newStr = VarModify(ctxt, &parsestate, unix_nstr, VarNoMatch,
+                                       pattern);
+                }
+                free(pattern);
+                break;
+            }
+            case 'S': {
+                VarPattern pattern;
+                Var_Parse_State tmpparsestate;
+
+                pattern.flags = 0;
+                tmpparsestate = parsestate;
+                delim = tstr[1];
+                tstr += 2;
+
+                /*
 		 * If pattern begins with '^', it is anchored to the
@@ -3308,22 +3335,22 @@ ApplyModifiers(char *nstr, const char *tstr,
 		 */
-		if (*tstr == '^') {
-		    pattern.flags |= VAR_MATCH_START;
-		    tstr += 1;
-		}
-
-		cp = tstr;
-		if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, flags,
-						 &cp, delim,
-						 &pattern.flags,
-						 &pattern.leftLen,
-						 NULL)) == NULL)
-		    goto cleanup;
-
-		if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
-						 &cp, delim, NULL,
-						 &pattern.rightLen,
-						 &pattern)) == NULL)
-		    goto cleanup;
-
-		/*
+                if (*tstr == '^') {
+                    pattern.flags |= VAR_MATCH_START;
+                    tstr += 1;
+                }
+
+                cp = tstr;
+                if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, flags,
+                                                 &cp, delim,
+                                                 &pattern.flags,
+                                                 &pattern.leftLen,
+                                                 NULL)) == NULL)
+                    goto cleanup;
+
+                if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
+                                                 &cp, delim, NULL,
+                                                 &pattern.rightLen,
+                                                 &pattern)) == NULL)
+                    goto cleanup;
+
+                /*
 		 * Check for global substitution. If 'g' after the final
@@ -3332,271 +3359,268 @@ ApplyModifiers(char *nstr, const char *tstr,
 		 */
-		for (;; cp++) {
-		    switch (*cp) {
-		    case 'g':
-			pattern.flags |= VAR_SUB_GLOBAL;
-			continue;
-		    case '1':
-			pattern.flags |= VAR_SUB_ONE;
-			continue;
-		    case 'W':
-			tmpparsestate.oneBigWord = TRUE;
-			continue;
-		    }
-		    break;
-		}
-
-		termc = *cp;
-		newStr = VarModify(ctxt, &tmpparsestate, nstr,
-				   VarSubstitute,
-				   &pattern);
-
-		/*
+                for (;; cp++) {
+                    switch (*cp) {
+                        case 'g':
+                            pattern.flags |= VAR_SUB_GLOBAL;
+                            continue;
+                        case '1':
+                            pattern.flags |= VAR_SUB_ONE;
+                            continue;
+                        case 'W':
+                            tmpparsestate.oneBigWord = TRUE;
+                            continue;
+                    }
+                    break;
+                }
+
+                termc = *cp;
+                newStr = VarModify(ctxt, &tmpparsestate, unix_nstr,
+                                   VarSubstitute,
+                                   &pattern);
+
+                /*
 		 * Free the two strings.
 		 */
-		free(UNCONST(pattern.lhs));
-		free(UNCONST(pattern.rhs));
-		delim = '\0';
-		break;
-	    }
-	case '?':
-	    {
-		VarPattern 	pattern;
-		Boolean	value;
-		int cond_rc;
-		int lhs_flags, rhs_flags;
-
-		/* find ':', and then substitute accordingly */
-		if (flags & VARF_WANTRES) {
-		    cond_rc = Cond_EvalExpression(NULL, v->name, &value, 0, FALSE);
-		    if (cond_rc == COND_INVALID) {
-			lhs_flags = rhs_flags = VAR_NOSUBST;
-		    } else if (value) {
-			lhs_flags = 0;
-			rhs_flags = VAR_NOSUBST;
-		    } else {
-			lhs_flags = VAR_NOSUBST;
-			rhs_flags = 0;
-		    }
-		} else {
-		    /* we are just consuming and discarding */
-		    cond_rc = value = 0;
-		    lhs_flags = rhs_flags = VAR_NOSUBST;
-		}
-		pattern.flags = 0;
-
-		cp = ++tstr;
-		delim = ':';
-		if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, flags,
-						 &cp, delim, &lhs_flags,
-						 &pattern.leftLen,
-						 NULL)) == NULL)
-		    goto cleanup;
-
-		/* BROPEN or PROPEN */
-		delim = endc;
-		if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
-						 &cp, delim, &rhs_flags,
-						 &pattern.rightLen,
-						 NULL)) == NULL)
-		    goto cleanup;
-
-		termc = *--cp;
-		delim = '\0';
-		if (cond_rc == COND_INVALID) {
-		    Error("Bad conditional expression `%s' in %s?%s:%s",
-			  v->name, v->name, pattern.lhs, pattern.rhs);
-		    goto cleanup;
-		}
-
-		if (value) {
-		    newStr = UNCONST(pattern.lhs);
-		    free(UNCONST(pattern.rhs));
-		} else {
-		    newStr = UNCONST(pattern.rhs);
-		    free(UNCONST(pattern.lhs));
-		}
-		if (v->flags & VAR_JUNK) {
-		    v->flags |= VAR_KEEP;
-		}
-		break;
-	    }
+                free(UNCONST(pattern.lhs));
+                free(UNCONST(pattern.rhs));
+                delim = '\0';
+                break;
+            }
+            case '?': {
+                VarPattern pattern;
+                Boolean value;
+                int cond_rc;
+                int lhs_flags, rhs_flags;
+
+                /* find ':', and then substitute accordingly */
+                if (flags & VARF_WANTRES) {
+                    cond_rc = Cond_EvalExpression(NULL, v->name, &value, 0, FALSE);
+                    if (cond_rc == COND_INVALID) {
+                        lhs_flags = rhs_flags = VAR_NOSUBST;
+                    } else if (value) {
+                        lhs_flags = 0;
+                        rhs_flags = VAR_NOSUBST;
+                    } else {
+                        lhs_flags = VAR_NOSUBST;
+                        rhs_flags = 0;
+                    }
+                } else {
+                    /* we are just consuming and discarding */
+                    cond_rc = value = 0;
+                    lhs_flags = rhs_flags = VAR_NOSUBST;
+                }
+                pattern.flags = 0;
+
+                cp = ++tstr;
+                delim = ':';
+                if ((pattern.lhs = VarGetPattern(ctxt, &parsestate, flags,
+                                                 &cp, delim, &lhs_flags,
+                                                 &pattern.leftLen,
+                                                 NULL)) == NULL)
+                    goto cleanup;
+
+                /* BROPEN or PROPEN */
+                delim = endc;
+                if ((pattern.rhs = VarGetPattern(ctxt, &parsestate, flags,
+                                                 &cp, delim, &rhs_flags,
+                                                 &pattern.rightLen,
+                                                 NULL)) == NULL)
+                    goto cleanup;
+
+                termc = *--cp;
+                delim = '\0';
+                if (cond_rc == COND_INVALID) {
+                    Error("Bad conditional expression `%s' in %s?%s:%s",
+                          v->name, v->name, pattern.lhs, pattern.rhs);
+                    goto cleanup;
+                }
+
+                if (value) {
+                    newStr = UNCONST(pattern.lhs);
+                    free(UNCONST(pattern.rhs));
+                } else {
+                    newStr = UNCONST(pattern.rhs);
+                    free(UNCONST(pattern.lhs));
+                }
+                if (v->flags & VAR_JUNK) {
+                    v->flags |= VAR_KEEP;
+                }
+                break;
+            }
 #ifndef NO_REGEX
-	case 'C':
-	    {
-		VarREPattern    pattern;
-		char           *re;
-		int             error;
-		Var_Parse_State tmpparsestate;
-
-		pattern.flags = 0;
-		tmpparsestate = parsestate;
-		delim = tstr[1];
-		tstr += 2;
-
-		cp = tstr;
-
-		if ((re = VarGetPattern(ctxt, &parsestate, flags, &cp, delim,
-					NULL, NULL, NULL)) == NULL)
-		    goto cleanup;
-
-		if ((pattern.replace = VarGetPattern(ctxt, &parsestate,
-						     flags, &cp, delim, NULL,
-						     NULL, NULL)) == NULL){
-		    free(re);
-		    goto cleanup;
-		}
-
-		for (;; cp++) {
-		    switch (*cp) {
-		    case 'g':
-			pattern.flags |= VAR_SUB_GLOBAL;
-			continue;
-		    case '1':
-			pattern.flags |= VAR_SUB_ONE;
-			continue;
-		    case 'W':
-			tmpparsestate.oneBigWord = TRUE;
-			continue;
-		    }
-		    break;
-		}
-
-		termc = *cp;
-
-		error = regcomp(&pattern.re, re, REG_EXTENDED);
-		free(re);
-		if (error)  {
-		    *lengthPtr = cp - start + 1;
-		    VarREError(error, &pattern.re, "RE substitution error");
-		    free(pattern.replace);
-		    goto cleanup;
-		}
-
-		pattern.nsub = pattern.re.re_nsub + 1;
-		if (pattern.nsub < 1)
-		    pattern.nsub = 1;
-		if (pattern.nsub > 10)
-		    pattern.nsub = 10;
-		pattern.matches = bmake_malloc(pattern.nsub *
-					  sizeof(regmatch_t));
-		newStr = VarModify(ctxt, &tmpparsestate, nstr,
-				   VarRESubstitute,
-				   &pattern);
-		regfree(&pattern.re);
-		free(pattern.replace);
-		free(pattern.matches);
-		delim = '\0';
-		break;
-	    }
+            case 'C': {
+                VarREPattern pattern;
+                char *re;
+                int error;
+                Var_Parse_State tmpparsestate;
+
+                pattern.flags = 0;
+                tmpparsestate = parsestate;
+                delim = tstr[1];
+                tstr += 2;
+
+                cp = tstr;
+
+                if ((re = VarGetPattern(ctxt, &parsestate, flags, &cp, delim,
+                                        NULL, NULL, NULL)) == NULL)
+                    goto cleanup;
+
+                if ((pattern.replace = VarGetPattern(ctxt, &parsestate,
+                                                     flags, &cp, delim, NULL,
+                                                     NULL, NULL)) == NULL) {
+                    free(re);
+                    goto cleanup;
+                }
+
+                for (;; cp++) {
+                    switch (*cp) {
+                        case 'g':
+                            pattern.flags |= VAR_SUB_GLOBAL;
+                            continue;
+                        case '1':
+                            pattern.flags |= VAR_SUB_ONE;
+                            continue;
+                        case 'W':
+                            tmpparsestate.oneBigWord = TRUE;
+                            continue;
+                    }
+                    break;
+                }
+
+                termc = *cp;
+
+                error = regcomp(&pattern.re, re, REG_EXTENDED);
+                free(re);
+                if (error) {
+                    *lengthPtr = cp - start + 1;
+                    VarREError(error, &pattern.re, "RE substitution error");
+                    free(pattern.replace);
+                    goto cleanup;
+                }
+
+                pattern.nsub = pattern.re.re_nsub + 1;
+                if (pattern.nsub < 1)
+                    pattern.nsub = 1;
+                if (pattern.nsub > 10)
+                    pattern.nsub = 10;
+                pattern.matches = bmake_malloc(pattern.nsub *
+                                               sizeof(regmatch_t));
+                newStr = VarModify(ctxt, &tmpparsestate, unix_nstr,
+                                   VarRESubstitute,
+                                   &pattern);
+                regfree(&pattern.re);
+                free(pattern.replace);
+                free(pattern.matches);
+                delim = '\0';
+                break;
+            }
 #endif
-	case 'q':
-	case 'Q':
-	    if (tstr[1] == endc || tstr[1] == ':') {
-		newStr = VarQuote(nstr, modifier == 'q');
-		cp = tstr + 1;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
-	case 'T':
-	    if (tstr[1] == endc || tstr[1] == ':') {
-		newStr = VarModify(ctxt, &parsestate, nstr, VarTail,
-				   NULL);
-		cp = tstr + 1;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
-	case 'H':
-	    if (tstr[1] == endc || tstr[1] == ':') {
-		newStr = VarModify(ctxt, &parsestate, nstr, VarHead,
-				   NULL);
-		cp = tstr + 1;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
-	case 'E':
-	    if (tstr[1] == endc || tstr[1] == ':') {
-		newStr = VarModify(ctxt, &parsestate, nstr, VarSuffix,
-				   NULL);
-		cp = tstr + 1;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
-	case 'R':
-	    if (tstr[1] == endc || tstr[1] == ':') {
-		newStr = VarModify(ctxt, &parsestate, nstr, VarRoot,
-				   NULL);
-		cp = tstr + 1;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
-	case 'r':
-	    cp = tstr + 1;	/* make sure it is set */
-	    if (STRMOD_MATCHX(tstr, "range", 5)) {
-		int n;
-
-		if (tstr[5] == '=') {
-		    n = strtoul(&tstr[6], &ep, 10);
-		    cp = ep;
-		} else {
-		    n = 0;
-		    cp = tstr + 5;
-		}
-		newStr = VarRange(nstr, n);
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
-	case 'O':
-	    {
-		char otype;
-
-		cp = tstr + 1;	/* skip to the rest in any case */
-		if (tstr[1] == endc || tstr[1] == ':') {
-		    otype = 's';
-		    termc = *cp;
-		} else if ( (tstr[1] == 'x') &&
-			    (tstr[2] == endc || tstr[2] == ':') ) {
-		    otype = tstr[1];
-		    cp = tstr + 2;
-		    termc = *cp;
-		} else {
-		    goto bad_modifier;
-		}
-		newStr = VarOrder(nstr, otype);
-		break;
-	    }
-	case 'u':
-	    if (tstr[1] == endc || tstr[1] == ':') {
-		newStr = VarUniq(nstr);
-		cp = tstr + 1;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
+            case 'q':
+            case 'Q':
+                if (tstr[1] == endc || tstr[1] == ':') {
+                    newStr = VarQuote(unix_nstr, modifier == 'q');
+                    cp = tstr + 1;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
+            case 'T':
+                if (tstr[1] == endc || tstr[1] == ':') {
+                    newStr = VarModify(ctxt, &parsestate, unix_nstr, VarTail,
+                                       NULL);
+                    cp = tstr + 1;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
+            case 'H':
+                if (tstr[1] == endc || tstr[1] == ':') {
+                    newStr = VarModify(ctxt, &parsestate, unix_nstr, VarHead,
+                                       NULL);
+                    cp = tstr + 1;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
+            case 'E':
+                if (tstr[1] == endc || tstr[1] == ':') {
+                    newStr = VarModify(ctxt, &parsestate, unix_nstr, VarSuffix,
+                                       NULL);
+                    cp = tstr + 1;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
+            case 'R':
+                if (tstr[1] == endc || tstr[1] == ':') {
+                    newStr = VarModify(ctxt, &parsestate, unix_nstr, VarRoot,
+                                       NULL);
+                    cp = tstr + 1;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
+            case 'r':
+                cp = tstr + 1;    /* make sure it is set */
+                if (STRMOD_MATCHX(tstr, "range", 5)) {
+                    int n;
+
+                    if (tstr[5] == '=') {
+                        n = strtoul(&tstr[6], &ep, 10);
+                        cp = ep;
+                    } else {
+                        n = 0;
+                        cp = tstr + 5;
+                    }
+                    newStr = VarRange(unix_nstr, n);
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
+            case 'O': {
+                char otype;
+
+                cp = tstr + 1;    /* skip to the rest in any case */
+                if (tstr[1] == endc || tstr[1] == ':') {
+                    otype = 's';
+                    termc = *cp;
+                } else if ((tstr[1] == 'x') &&
+                           (tstr[2] == endc || tstr[2] == ':')) {
+                    otype = tstr[1];
+                    cp = tstr + 2;
+                    termc = *cp;
+                } else {
+                    goto bad_modifier;
+                }
+                newStr = VarOrder(unix_nstr, otype);
+                break;
+            }
+            case 'u':
+                if (tstr[1] == endc || tstr[1] == ':') {
+                    newStr = VarUniq(unix_nstr);
+                    cp = tstr + 1;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
 #ifdef SUNSHCMD
-	case 's':
-	    if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
-		const char *emsg;
-		if (flags & VARF_WANTRES) {
-		    newStr = Cmd_Exec(nstr, &emsg);
-		    if (emsg)
-			Error(emsg, nstr);
-		} else
-		    newStr = varNoError;
-		cp = tstr + 2;
-		termc = *cp;
-		break;
-	    }
-	    goto default_case;
+            case 's':
+                if (tstr[1] == 'h' && (tstr[2] == endc || tstr[2] == ':')) {
+                    const char *emsg;
+                    if (flags & VARF_WANTRES) {
+                        newStr = Cmd_Exec(unix_nstr, &emsg);
+                        if (emsg)
+                            Error(emsg, unix_nstr);
+                    } else
+                        newStr = varNoError;
+                    cp = tstr + 2;
+                    termc = *cp;
+                    break;
+                }
+                goto default_case;
 #endif
-	default:
-	default_case:
-	{
+            default:
+            default_case:
+            {
 #ifdef SYSVVARSUB
-	    /*
+                /*
 	     * This can either be a bogus modifier or a System-V
@@ -3604,8 +3628,8 @@ ApplyModifiers(char *nstr, const char *tstr,
 	     */
-	    VarPattern      pattern;
-	    Boolean         eqFound;
+                VarPattern pattern;
+                Boolean eqFound;

-	    pattern.flags = 0;
-	    eqFound = FALSE;
-	    /*
+                pattern.flags = 0;
+                eqFound = FALSE;
+                /*
 	     * First we make a pass through the string trying
@@ -3614,19 +3638,18 @@ ApplyModifiers(char *nstr, const char *tstr,
 	     */
-	    cp = tstr;
-	    cnt = 1;
-	    while (*cp != '\0' && cnt) {
-		if (*cp == '=') {
-		    eqFound = TRUE;
-		    /* continue looking for endc */
-		}
-		else if (*cp == endc)
-		    cnt--;
-		else if (*cp == startc)
-		    cnt++;
-		if (cnt)
-		    cp++;
-	    }
-	    if (*cp == endc && eqFound) {
-
-		/*
+                cp = tstr;
+                cnt = 1;
+                while (*cp != '\0' && cnt) {
+                    if (*cp == '=') {
+                        eqFound = TRUE;
+                        /* continue looking for endc */
+                    } else if (*cp == endc)
+                        cnt--;
+                    else if (*cp == startc)
+                        cnt++;
+                    if (cnt)
+                        cp++;
+                }
+                if (*cp == endc && eqFound) {
+
+                    /*
 		 * Now we break this sucker into the lhs and
@@ -3634,15 +3657,15 @@ ApplyModifiers(char *nstr, const char *tstr,
 		 */
-		delim='=';
-		cp = tstr;
-		if ((pattern.lhs = VarGetPattern(ctxt, &parsestate,
-						 flags, &cp, delim, &pattern.flags,
-						 &pattern.leftLen, NULL)) == NULL)
-		    goto cleanup;
-		delim = endc;
-		if ((pattern.rhs = VarGetPattern(ctxt, &parsestate,
-						 flags, &cp, delim, NULL, &pattern.rightLen,
-						 &pattern)) == NULL)
-		    goto cleanup;
-
-		/*
+                    delim = '=';
+                    cp = tstr;
+                    if ((pattern.lhs = VarGetPattern(ctxt, &parsestate,
+                                                     flags, &cp, delim, &pattern.flags,
+                                                     &pattern.leftLen, NULL)) == NULL)
+                        goto cleanup;
+                    delim = endc;
+                    if ((pattern.rhs = VarGetPattern(ctxt, &parsestate,
+                                                     flags, &cp, delim, NULL, &pattern.rightLen,
+                                                     &pattern)) == NULL)
+                        goto cleanup;
+
+                    /*
 		 * SYSV modifications happen through the whole
@@ -3650,62 +3673,63 @@ ApplyModifiers(char *nstr, const char *tstr,
 		 */
-		termc = *--cp;
-		delim = '\0';
-		if (pattern.leftLen == 0 && *nstr == '\0') {
-		    newStr = nstr;	/* special case */
-		} else {
-		    newStr = VarModify(ctxt, &parsestate, nstr,
-				       VarSYSVMatch,
-				       &pattern);
-		}
-		free(UNCONST(pattern.lhs));
-		free(UNCONST(pattern.rhs));
-	    } else
+                    termc = *--cp;
+                    delim = '\0';
+                    if (pattern.leftLen == 0 && *unix_nstr == '\0') {
+                        newStr = unix_nstr;    /* special case */
+                    } else {
+                        newStr = VarModify(ctxt, &parsestate, unix_nstr,
+                                           VarSYSVMatch,
+                                           &pattern);
+                    }
+                    free(UNCONST(pattern.lhs));
+                    free(UNCONST(pattern.rhs));
+                } else
 #endif
-		{
-		    Error("Unknown modifier '%c'", *tstr);
-		    for (cp = tstr+1;
-			 *cp != ':' && *cp != endc && *cp != '\0';
-			 cp++)
-			continue;
-		    termc = *cp;
-		    newStr = var_Error;
-		}
-	    }
-	}
-	if (DEBUG(VAR)) {
-	    fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
-		v->name, modifier, newStr);
-	}
-
-	if (newStr != nstr) {
-	    if (*freePtr) {
-		free(nstr);
-		*freePtr = NULL;
-	    }
-	    nstr = newStr;
-	    if (nstr != var_Error && nstr != varNoError) {
-		*freePtr = nstr;
-	    }
-	}
-	if (termc == '\0' && endc != '\0') {
-	    Error("Unclosed variable specification (expecting '%c') for \"%s\" (value \"%s\") modifier %c", endc, v->name, nstr, modifier);
-	} else if (termc == ':') {
-	    cp++;
-	}
-	tstr = cp;
-    }
- out:
+                {
+                    Error("Unknown modifier '%c'", *tstr);
+                    for (cp = tstr + 1;
+                         *cp != ':' && *cp != endc && *cp != '\0';
+                         cp++)
+                        continue;
+                    termc = *cp;
+                    newStr = var_Error;
+                }
+            }
+        }
+        if (DEBUG(VAR)) {
+            fprintf(debug_file, "Result[%s] of :%c is \"%s\"\n",
+                    v->name, modifier, newStr);
+        }
+
+        if (newStr != unix_nstr) {
+            if (*freePtr) {
+                free(unix_nstr);
+                *freePtr = NULL;
+            }
+            unix_nstr = newStr;
+            if (unix_nstr != var_Error && unix_nstr != varNoError) {
+                *freePtr = unix_nstr;
+            }
+        }
+        if (termc == '\0' && endc != '\0') {
+            Error("Unclosed variable specification (expecting '%c') for \"%s\" (value \"%s\") modifier %c", endc,
+                  v->name, unix_nstr, modifier);
+        } else if (termc == ':') {
+            cp++;
+        }
+        tstr = cp;
+    }
+    out:
     *lengthPtr = tstr - start;
-    return (nstr);
+    return (unix_nstr);

- bad_modifier:
+    bad_modifier:
     /* "{(" */
-    Error("Bad modifier `:%.*s' for %s", (int)strcspn(tstr, ":)}"), tstr,
-	  v->name);
+    Error("Bad modifier `:%.*s' for %s", (int) strcspn(tstr, ":)}"), tstr,
+          v->name);

- cleanup:
+    cleanup:
     *lengthPtr = cp - start;
     if (delim != '\0')
-	Error("Unclosed substitution for %s (%c missing)",
-	      v->name, delim);
+        Error("Unclosed substitution for %s (%c missing)",
+              v->name, delim);
     free(*freePtr);
@@ -3747,15 +3771,14 @@ char *
 Var_Parse(const char *str, GNode *ctxt, int flags,
-	  int *lengthPtr, void **freePtr)
-{
-    const char	   *tstr;    	/* Pointer into str */
-    Var		   *v;		/* Variable in invocation */
-    Boolean 	    haveModifier;/* TRUE if have modifiers for the variable */
-    char	    endc;    	/* Ending character when variable in parens
+          int *lengthPtr, void **freePtr) {
+    const char *tstr;        /* Pointer into str */
+    Var *v;        /* Variable in invocation */
+    Boolean haveModifier;/* TRUE if have modifiers for the variable */
+    char endc;        /* Ending character when variable in parens
 				 * or braces */
-    char	    startc;	/* Starting character when variable in parens
+    char startc;    /* Starting character when variable in parens
 				 * or braces */
-    int		    vlen;	/* Length of variable name */
-    const char 	   *start;	/* Points to original start of str */
-    char	   *nstr;	/* New string, used during expansion */
-    Boolean 	    dynamic;	/* TRUE if the variable is local and we're
+    int vlen;    /* Length of variable name */
+    const char *start;    /* Points to original start of str */
+    char *nstr;    /* New string, used during expansion */
+    Boolean dynamic;    /* TRUE if the variable is local and we're
 				 * expanding it in a non-local context. This
@@ -3763,4 +3786,4 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 				 * result is just the invocation, unaltered */
-    const char     *extramodifiers; /* extra modifiers to apply first */
-    char	  name[2];
+    const char *extramodifiers; /* extra modifiers to apply first */
+    char name[2];

@@ -3773,3 +3796,3 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
     if (startc != PROPEN && startc != BROPEN) {
-	/*
+        /*
 	 * If it's not bounded by braces of some sort, life is much simpler.
@@ -3779,16 +3802,16 @@ Var_Parse(const char *str, GNode *ctxt, int flags,

-	/* Error out some really stupid names */
-	if (startc == '\0' || strchr(")}:$", startc)) {
-	    *lengthPtr = 1;
-	    return var_Error;
-	}
-	name[0] = startc;
-	name[1] = '\0';
+        /* Error out some really stupid names */
+        if (startc == '\0' || strchr(")}:$", startc)) {
+            *lengthPtr = 1;
+            return var_Error;
+        }
+        name[0] = startc;
+        name[1] = '\0';

-	v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
-	if (v == NULL) {
-	    *lengthPtr = 2;
+        v = VarFind(name, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
+        if (v == NULL) {
+            *lengthPtr = 2;

-	    if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
-		/*
+            if ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)) {
+                /*
 		 * If substituting a local variable in a non-local context,
@@ -3801,69 +3824,67 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 		 */
-		switch (str[1]) {
-		    case '@':
-			return UNCONST("$(.TARGET)");
-		    case '%':
-			return UNCONST("$(.MEMBER)");
-		    case '*':
-			return UNCONST("$(.PREFIX)");
-		    case '!':
-			return UNCONST("$(.ARCHIVE)");
-		}
-	    }
-	    /*
+                switch (str[1]) {
+                    case '@':
+                        return UNCONST("$(.TARGET)");
+                    case '%':
+                        return UNCONST("$(.MEMBER)");
+                    case '*':
+                        return UNCONST("$(.PREFIX)");
+                    case '!':
+                        return UNCONST("$(.ARCHIVE)");
+                }
+            }
+            /*
 	     * Error
 	     */
-	    return (flags & VARF_UNDEFERR) ? var_Error : varNoError;
-	} else {
-	    haveModifier = FALSE;
-	    tstr = &str[1];
-	    endc = str[1];
-	}
+            return (flags & VARF_UNDEFERR) ? var_Error : varNoError;
+        } else {
+            haveModifier = FALSE;
+            tstr = &str[1];
+            endc = str[1];
+        }
     } else {
-	Buffer buf;	/* Holds the variable name */
-	int depth = 1;
+        Buffer buf;    /* Holds the variable name */
+        int depth = 1;

-	endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
-	Buf_Init(&buf, 0);
+        endc = startc == PROPEN ? PRCLOSE : BRCLOSE;
+        Buf_Init(&buf, 0);

-	/*
+        /*
 	 * Skip to the end character or a colon, whichever comes first.
 	 */
-	for (tstr = str + 2; *tstr != '\0'; tstr++)
-	{
-	    /*
+        for (tstr = str + 2; *tstr != '\0'; tstr++) {
+            /*
 	     * Track depth so we can spot parse errors.
 	     */
-	    if (*tstr == startc) {
-		depth++;
-	    }
-	    if (*tstr == endc) {
-		if (--depth == 0)
-		    break;
-	    }
-	    if (depth == 1 && *tstr == ':') {
-		break;
-	    }
-	    /*
+            if (*tstr == startc) {
+                depth++;
+            }
+            if (*tstr == endc) {
+                if (--depth == 0)
+                    break;
+            }
+            if (depth == 1 && *tstr == ':') {
+                break;
+            }
+            /*
 	     * A variable inside a variable, expand
 	     */
-	    if (*tstr == '$') {
-		int rlen;
-		void *freeIt;
-		char *rval = Var_Parse(tstr, ctxt, flags,  &rlen, &freeIt);
-		if (rval != NULL) {
-		    Buf_AddBytes(&buf, strlen(rval), rval);
-		}
-		free(freeIt);
-		tstr += rlen - 1;
-	    }
-	    else
-		Buf_AddByte(&buf, *tstr);
-	}
-	if (*tstr == ':') {
-	    haveModifier = TRUE;
-	} else if (*tstr == endc) {
-	    haveModifier = FALSE;
-	} else {
-	    /*
+            if (*tstr == '$') {
+                int rlen;
+                void *freeIt;
+                char *rval = Var_Parse(tstr, ctxt, flags, &rlen, &freeIt);
+                if (rval != NULL) {
+                    Buf_AddBytes(&buf, strlen(rval), rval);
+                }
+                free(freeIt);
+                tstr += rlen - 1;
+            } else
+                Buf_AddByte(&buf, *tstr);
+        }
+        if (*tstr == ':') {
+            haveModifier = TRUE;
+        } else if (*tstr == endc) {
+            haveModifier = FALSE;
+        } else {
+            /*
 	     * If we never did find the end character, return NULL
@@ -3872,9 +3893,9 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 	     */
-	    *lengthPtr = tstr - str;
-	    Buf_Destroy(&buf, TRUE);
-	    return (var_Error);
-	}
-	str = Buf_GetAll(&buf, &vlen);
+            *lengthPtr = tstr - str;
+            Buf_Destroy(&buf, TRUE);
+            return (var_Error);
+        }
+        str = Buf_GetAll(&buf, &vlen);

-	/*
+        /*
 	 * At this point, str points into newly allocated memory from
@@ -3889,4 +3910,4 @@ Var_Parse(const char *str, GNode *ctxt, int flags,

-	v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
-	/*
+        v = VarFind(str, ctxt, FIND_ENV | FIND_GLOBAL | FIND_CMD);
+        /*
 	 * Check also for bogus D and F forms of local variables since we're
@@ -3894,28 +3915,26 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 	 */
-	if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
-		(vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
-		strchr("@%?*!<>", str[0]) != NULL) {
-	    /*
+        if ((v == NULL) && (ctxt != VAR_CMD) && (ctxt != VAR_GLOBAL) &&
+            (vlen == 2) && (str[1] == 'F' || str[1] == 'D') &&
+            strchr("@%?*!<>", str[0]) != NULL) {
+            /*
 	     * Well, it's local -- go look for it.
 	     */
-	    name[0] = *str;
-	    name[1] = '\0';
-	    v = VarFind(name, ctxt, 0);
-
-	    if (v != NULL) {
-		if (str[1] == 'D') {
-			extramodifiers = "H:";
-		}
-		else { /* F */
-			extramodifiers = "T:";
-		}
-	    }
-	}
-
-	if (v == NULL) {
-	    if (((vlen == 1) ||
-		 (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
-		((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
-	    {
-		/*
+            name[0] = *str;
+            name[1] = '\0';
+            v = VarFind(name, ctxt, 0);
+
+            if (v != NULL) {
+                if (str[1] == 'D') {
+                    extramodifiers = "H:";
+                } else { /* F */
+                    extramodifiers = "T:";
+                }
+            }
+        }
+
+        if (v == NULL) {
+            if (((vlen == 1) ||
+                 (((vlen == 2) && (str[1] == 'F' || str[1] == 'D')))) &&
+                ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) {
+                /*
 		 * If substituting a local variable in a non-local context,
@@ -3928,28 +3947,26 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 		 */
-		switch (*str) {
-		    case '@':
-		    case '%':
-		    case '*':
-		    case '!':
-			dynamic = TRUE;
-			break;
-		}
-	    } else if ((vlen > 2) && (*str == '.') &&
-		       isupper((unsigned char) str[1]) &&
-		       ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL)))
-	    {
-		int	len;
-
-		len = vlen - 1;
-		if ((strncmp(str, ".TARGET", len) == 0) ||
-		    (strncmp(str, ".ARCHIVE", len) == 0) ||
-		    (strncmp(str, ".PREFIX", len) == 0) ||
-		    (strncmp(str, ".MEMBER", len) == 0))
-		{
-		    dynamic = TRUE;
-		}
-	    }
-
-	    if (!haveModifier) {
-		/*
+                switch (*str) {
+                    case '@':
+                    case '%':
+                    case '*':
+                    case '!':
+                        dynamic = TRUE;
+                        break;
+                }
+            } else if ((vlen > 2) && (*str == '.') &&
+                       isupper((unsigned char) str[1]) &&
+                       ((ctxt == VAR_CMD) || (ctxt == VAR_GLOBAL))) {
+                int len;
+
+                len = vlen - 1;
+                if ((strncmp(str, ".TARGET", len) == 0) ||
+                    (strncmp(str, ".ARCHIVE", len) == 0) ||
+                    (strncmp(str, ".PREFIX", len) == 0) ||
+                    (strncmp(str, ".MEMBER", len) == 0)) {
+                    dynamic = TRUE;
+                }
+            }
+
+            if (!haveModifier) {
+                /*
 		 * No modifiers -- have specification length so we can return
@@ -3957,14 +3974,14 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 		 */
-		*lengthPtr = tstr - start + 1;
-		if (dynamic) {
-		    char *pstr = bmake_strndup(start, *lengthPtr);
-		    *freePtr = pstr;
-		    Buf_Destroy(&buf, TRUE);
-		    return(pstr);
-		} else {
-		    Buf_Destroy(&buf, TRUE);
-		    return (flags & VARF_UNDEFERR) ? var_Error : varNoError;
-		}
-	    } else {
-		/*
+                *lengthPtr = tstr - start + 1;
+                if (dynamic) {
+                    char *pstr = bmake_strndup(start, *lengthPtr);
+                    *freePtr = pstr;
+                    Buf_Destroy(&buf, TRUE);
+                    return (pstr);
+                } else {
+                    Buf_Destroy(&buf, TRUE);
+                    return (flags & VARF_UNDEFERR) ? var_Error : varNoError;
+                }
+            } else {
+                /*
 		 * Still need to get to the end of the variable specification,
@@ -3972,10 +3989,10 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 		 */
-		v = bmake_malloc(sizeof(Var));
-		v->name = UNCONST(str);
-		Buf_Init(&v->val, 1);
-		v->flags = VAR_JUNK;
-		Buf_Destroy(&buf, FALSE);
-	    }
-	} else
-	    Buf_Destroy(&buf, TRUE);
+                v = bmake_malloc(sizeof(Var));
+                v->name = UNCONST(str);
+                Buf_Init(&v->val, 1);
+                v->flags = VAR_JUNK;
+                Buf_Destroy(&buf, FALSE);
+            }
+        } else
+            Buf_Destroy(&buf, TRUE);
     }
@@ -3983,6 +4000,6 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
     if (v->flags & VAR_IN_USE) {
-	Fatal("Variable %s is recursive.", v->name);
-	/*NOTREACHED*/
+        Fatal("Variable %s is recursive.", v->name);
+        /*NOTREACHED*/
     } else {
-	v->flags |= VAR_IN_USE;
+        v->flags |= VAR_IN_USE;
     }
@@ -3999,4 +4016,4 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
     if (strchr(nstr, '$') != NULL) {
-	nstr = Var_Subst(NULL, nstr, ctxt, flags);
-	*freePtr = nstr;
+        nstr = Var_Subst(NULL, nstr, ctxt, flags);
+        *freePtr = nstr;
     }
@@ -4006,27 +4023,27 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
     if ((nstr != NULL) && (haveModifier || extramodifiers != NULL)) {
-	void *extraFree;
-	int used;
-
-	extraFree = NULL;
-	if (extramodifiers != NULL) {
-		nstr = ApplyModifiers(nstr, extramodifiers, '(', ')',
-				      v, ctxt, flags, &used, &extraFree);
-	}
-
-	if (haveModifier) {
-		/* Skip initial colon. */
-		tstr++;
-
-		nstr = ApplyModifiers(nstr, tstr, startc, endc,
-				      v, ctxt, flags, &used, freePtr);
-		tstr += used;
-		free(extraFree);
-	} else {
-		*freePtr = extraFree;
-	}
+        void *extraFree;
+        int used;
+
+        extraFree = NULL;
+        if (extramodifiers != NULL) {
+            nstr = ApplyModifiers(nstr, extramodifiers, '(', ')',
+                                  v, ctxt, flags, &used, &extraFree);
+        }
+
+        if (haveModifier) {
+            /* Skip initial colon. */
+            tstr++;
+
+            nstr = ApplyModifiers(nstr, tstr, startc, endc,
+                                  v, ctxt, flags, &used, freePtr);
+            tstr += used;
+            free(extraFree);
+        } else {
+            *freePtr = extraFree;
+        }
     }
     if (*tstr) {
-	*lengthPtr = tstr - start + 1;
+        *lengthPtr = tstr - start + 1;
     } else {
-	*lengthPtr = tstr - start;
+        *lengthPtr = tstr - start;
     }
@@ -4034,8 +4051,8 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
     if (v->flags & VAR_FROM_ENV) {
-	Boolean	  destroy = FALSE;
+        Boolean destroy = FALSE;

-	if (nstr != Buf_GetAll(&v->val, NULL)) {
-	    destroy = TRUE;
-	} else {
-	    /*
+        if (nstr != Buf_GetAll(&v->val, NULL)) {
+            destroy = TRUE;
+        } else {
+            /*
 	     * Returning the value unmodified, so tell the caller to free
@@ -4043,7 +4060,7 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 	     */
-	    *freePtr = nstr;
-	}
-	VarFreeEnv(v, destroy);
+            *freePtr = nstr;
+        }
+        VarFreeEnv(v, destroy);
     } else if (v->flags & VAR_JUNK) {
-	/*
+        /*
 	 * Perform any free'ing needed and set *freePtr to NULL so the caller
@@ -4052,18 +4069,18 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 	 */
-	if (!(v->flags & VAR_KEEP)) {
-	    if (*freePtr) {
-		free(nstr);
-		*freePtr = NULL;
-	    }
-	    if (dynamic) {
-		nstr = bmake_strndup(start, *lengthPtr);
-		*freePtr = nstr;
-	    } else {
-		nstr = (flags & VARF_UNDEFERR) ? var_Error : varNoError;
-	    }
-	}
-	if (nstr != Buf_GetAll(&v->val, NULL))
-	    Buf_Destroy(&v->val, TRUE);
-	free(v->name);
-	free(v);
+        if (!(v->flags & VAR_KEEP)) {
+            if (*freePtr) {
+                free(nstr);
+                *freePtr = NULL;
+            }
+            if (dynamic) {
+                nstr = bmake_strndup(start, *lengthPtr);
+                *freePtr = nstr;
+            } else {
+                nstr = (flags & VARF_UNDEFERR) ? var_Error : varNoError;
+            }
+        }
+        if (nstr != Buf_GetAll(&v->val, NULL))
+            Buf_Destroy(&v->val, TRUE);
+        free(v->name);
+        free(v);
     }
@@ -4095,9 +4112,8 @@ Var_Parse(const char *str, GNode *ctxt, int flags,
 char *
-Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
-{
-    Buffer  	  buf;		    /* Buffer for forming things */
-    char    	  *val;		    /* Value to substitute for a variable */
-    int		  length;   	    /* Length of the variable invocation */
-    Boolean	  trailingBslash;   /* variable ends in \ */
-    void 	  *freeIt = NULL;    /* Set if it should be freed */
+Var_Subst(const char *var, const char *str, GNode *ctxt, int flags) {
+    Buffer buf;            /* Buffer for forming things */
+    char *val;            /* Value to substitute for a variable */
+    int length;        /* Length of the variable invocation */
+    Boolean trailingBslash;   /* variable ends in \ */
+    void *freeIt = NULL;    /* Set if it should be freed */
     static Boolean errorReported;   /* Set true if an error has already
@@ -4111,6 +4127,6 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
     while (*str) {
-	if (*str == '\n' && trailingBslash)
-	    Buf_AddByte(&buf, ' ');
-	if (var == NULL && (*str == '$') && (str[1] == '$')) {
-	    /*
+        if (*str == '\n' && trailingBslash)
+            Buf_AddByte(&buf, ' ');
+        if (var == NULL && (*str == '$') && (str[1] == '$')) {
+            /*
 	     * A dollar sign may be escaped either with another dollar sign.
@@ -4119,9 +4135,9 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 	     */
-	    if (save_dollars && (flags & VARF_ASSIGN))
-		Buf_AddByte(&buf, *str);
-	    str++;
-	    Buf_AddByte(&buf, *str);
-	    str++;
-	} else if (*str != '$') {
-	    /*
+            if (save_dollars && (flags & VARF_ASSIGN))
+                Buf_AddByte(&buf, *str);
+            str++;
+            Buf_AddByte(&buf, *str);
+            str++;
+        } else if (*str != '$') {
+            /*
 	     * Skip as many characters as possible -- either to the end of
@@ -4129,37 +4145,35 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 	     */
-	    const char  *cp;
-
-	    for (cp = str++; *str != '$' && *str != '\0'; str++)
-		continue;
-	    Buf_AddBytes(&buf, str - cp, cp);
-	} else {
-	    if (var != NULL) {
-		int expand;
-		for (;;) {
-		    if (str[1] == '\0') {
-			/* A trailing $ is kind of a special case */
-			Buf_AddByte(&buf, str[0]);
-			str++;
-			expand = FALSE;
-		    } else if (str[1] != PROPEN && str[1] != BROPEN) {
-			if (str[1] != *var || strlen(var) > 1) {
-			    Buf_AddBytes(&buf, 2, str);
-			    str += 2;
-			    expand = FALSE;
-			}
-			else
-			    expand = TRUE;
-			break;
-		    }
-		    else {
-			const char *p;
-
-			/*
+            const char *cp;
+
+            for (cp = str++; *str != '$' && *str != '\0'; str++)
+                continue;
+            Buf_AddBytes(&buf, str - cp, cp);
+        } else {
+            if (var != NULL) {
+                int expand;
+                for (;;) {
+                    if (str[1] == '\0') {
+                        /* A trailing $ is kind of a special case */
+                        Buf_AddByte(&buf, str[0]);
+                        str++;
+                        expand = FALSE;
+                    } else if (str[1] != PROPEN && str[1] != BROPEN) {
+                        if (str[1] != *var || strlen(var) > 1) {
+                            Buf_AddBytes(&buf, 2, str);
+                            str += 2;
+                            expand = FALSE;
+                        } else
+                            expand = TRUE;
+                        break;
+                    } else {
+                        const char *p;
+
+                        /*
 			 * Scan up to the end of the variable name.
 			 */
-			for (p = &str[2]; *p &&
-			     *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++)
-			    if (*p == '$')
-				break;
-			/*
+                        for (p = &str[2]; *p &&
+                                          *p != ':' && *p != PRCLOSE && *p != BRCLOSE; p++)
+                            if (*p == '$')
+                                break;
+                        /*
 			 * A variable inside the variable. We cannot expand
@@ -4168,11 +4182,11 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 			 */
-			if (*p == '$') {
-			    Buf_AddBytes(&buf, p - str, str);
-			    str = p;
-			    continue;
-			}
-
-			if (strncmp(var, str + 2, p - str - 2) != 0 ||
-			    var[p - str - 2] != '\0') {
-			    /*
+                        if (*p == '$') {
+                            Buf_AddBytes(&buf, p - str, str);
+                            str = p;
+                            continue;
+                        }
+
+                        if (strncmp(var, str + 2, p - str - 2) != 0 ||
+                            var[p - str - 2] != '\0') {
+                            /*
 			     * Not the variable we want to expand, scan
@@ -4180,20 +4194,19 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 			     */
-			    for (;*p != '$' && *p != '\0'; p++)
-				continue;
-			    Buf_AddBytes(&buf, p - str, str);
-			    str = p;
-			    expand = FALSE;
-			}
-			else
-			    expand = TRUE;
-			break;
-		    }
-		}
-		if (!expand)
-		    continue;
-	    }
-
-	    val = Var_Parse(str, ctxt, flags, &length, &freeIt);
-
-	    /*
+                            for (; *p != '$' && *p != '\0'; p++)
+                                continue;
+                            Buf_AddBytes(&buf, p - str, str);
+                            str = p;
+                            expand = FALSE;
+                        } else
+                            expand = TRUE;
+                        break;
+                    }
+                }
+                if (!expand)
+                    continue;
+            }
+
+            val = Var_Parse(str, ctxt, flags, &length, &freeIt);
+
+            /*
 	     * When we come down here, val should either point to the
@@ -4203,4 +4216,4 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 	     */
-	    if (val == var_Error || val == varNoError) {
-		/*
+            if (val == var_Error || val == varNoError) {
+                /*
 		 * If performing old-time variable substitution, skip over
@@ -4210,6 +4223,6 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 		 */
-		if (oldVars) {
-		    str += length;
-		} else if ((flags & VARF_UNDEFERR) || val == var_Error) {
-		    /*
+                if (oldVars) {
+                    str += length;
+                } else if ((flags & VARF_UNDEFERR) || val == var_Error) {
+                    /*
 		     * If variable is undefined, complain and skip the
@@ -4218,14 +4231,14 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 		     */
-		    if (!errorReported) {
-			Parse_Error(PARSE_FATAL,
-				     "Undefined variable \"%.*s\"",length,str);
-		    }
-		    str += length;
-		    errorReported = TRUE;
-		} else {
-		    Buf_AddByte(&buf, *str);
-		    str += 1;
-		}
-	    } else {
-		/*
+                    if (!errorReported) {
+                        Parse_Error(PARSE_FATAL,
+                                    "Undefined variable \"%.*s\"", length, str);
+                    }
+                    str += length;
+                    errorReported = TRUE;
+                } else {
+                    Buf_AddByte(&buf, *str);
+                    str += 1;
+                }
+            } else {
+                /*
 		 * We've now got a variable structure to store in. But first,
@@ -4233,5 +4246,5 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 		 */
-		str += length;
+                str += length;

-		/*
+                /*
 		 * Copy all the characters from the variable value straight
@@ -4239,9 +4252,9 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 		 */
-		length = strlen(val);
-		Buf_AddBytes(&buf, length, val);
-		trailingBslash = length > 0 && val[length - 1] == '\\';
-	    }
-	    free(freeIt);
-	    freeIt = NULL;
-	}
+                length = strlen(val);
+                Buf_AddBytes(&buf, length, val);
+                trailingBslash = length > 0 && val[length - 1] == '\\';
+            }
+            free(freeIt);
+            freeIt = NULL;
+        }
     }
@@ -4269,3 +4282,3 @@ Var_Subst(const char *var, const char *str, GNode *ctxt, int flags)
 #if 0
-char *
+                                                                                                                        char *
 Var_GetTail(char *file)
@@ -4313,4 +4326,3 @@ Var_GetHead(char *file)
 void
-Var_Init(void)
-{
+Var_Init(void) {
     VAR_INTERNAL = Targ_NewGN("Internal");
@@ -4323,4 +4335,3 @@ Var_Init(void)
 void
-Var_End(void)
-{
+Var_End(void) {
 }
@@ -4330,5 +4341,4 @@ Var_End(void)
 static void
-VarPrintVar(void *vp)
-{
-    Var    *v = (Var *)vp;
+VarPrintVar(void *vp) {
+    Var *v = (Var *) vp;
     fprintf(debug_file, "%-16s = %s\n", v->name, Buf_GetAll(&v->val, NULL));
@@ -4343,4 +4353,3 @@ VarPrintVar(void *vp)
 void
-Var_Dump(GNode *ctxt)
-{
+Var_Dump(GNode *ctxt) {
     Hash_Search search;
@@ -4349,6 +4358,6888 @@ Var_Dump(GNode *ctxt)
     for (h = Hash_EnumFirst(&ctxt->context, &search);
-	 h != NULL;
-	 h = Hash_EnumNext(&search)) {
-	    VarPrintVar(Hash_GetValue(h));
+         h != NULL;
+         h = Hash_EnumNext(&search)) {
+        VarPrintVar(Hash_GetValue(h));
+    }
+}
+
+#if (!defined(HAVE_REGCOMP) || !defined(HAVE_REGERROR) || !defined(HAVE_REGEXEC) || !defined(HAVE_REGFREE))
+
+extern char * nl_langinfo(nl_item item);
+
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+static void re_string_construct_common(const char *str, Idx len,
+                                       re_string_t *pstr,
+                                       RE_TRANSLATE_TYPE trans, bool icase,
+                                       const re_dfa_t *dfa);
+
+static re_dfastate_t *create_ci_newstate(const re_dfa_t *dfa,
+                                         const re_node_set *nodes,
+                                         re_hashval_t hash);
+
+static re_dfastate_t *create_cd_newstate(const re_dfa_t *dfa,
+                                         const re_node_set *nodes,
+                                         unsigned int context,
+                                         re_hashval_t hash);
+
+static reg_errcode_t re_string_realloc_buffers(re_string_t *pstr,
+                                               Idx new_buf_len);
+
+static void build_upper_buffer(re_string_t *pstr);
+
+static void re_string_translate_buffer(re_string_t *pstr);
+
+static unsigned int re_string_context_at(const re_string_t *input, Idx idx,
+                                         int eflags) __attribute__ ((pure));
+
+static reg_errcode_t match_ctx_init(re_match_context_t *cache, int eflags,
+                                    Idx n);
+
+static void match_ctx_clean(re_match_context_t *mctx);
+
+static void match_ctx_free(re_match_context_t *cache);
+
+static reg_errcode_t match_ctx_add_entry(re_match_context_t *cache, Idx node,
+                                         Idx str_idx, Idx from, Idx to);
+
+static Idx search_cur_bkref_entry(const re_match_context_t *mctx, Idx str_idx);
+
+static reg_errcode_t match_ctx_add_subtop(re_match_context_t *mctx, Idx node,
+                                          Idx str_idx);
+
+static re_sub_match_last_t *match_ctx_add_sublast(re_sub_match_top_t *subtop,
+                                                  Idx node, Idx str_idx);
+
+static void sift_ctx_init(re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+                          re_dfastate_t **limited_sts, Idx last_node,
+                          Idx last_str_idx);
+
+static reg_errcode_t re_search_internal(const regex_t *preg,
+                                        const char *string, Idx length,
+                                        Idx start, Idx last_start, Idx stop,
+                                        size_t nmatch, regmatch_t pmatch[],
+                                        int eflags);
+
+static regoff_t re_search_2_stub(struct re_pattern_buffer *bufp,
+                                 const char *string1, Idx length1,
+                                 const char *string2, Idx length2,
+                                 Idx start, regoff_t range,
+                                 struct re_registers *regs,
+                                 Idx stop, bool ret_len);
+
+static regoff_t re_search_stub(struct re_pattern_buffer *bufp,
+                               const char *string, Idx length, Idx start,
+                               regoff_t range, Idx stop,
+                               struct re_registers *regs,
+                               bool ret_len);
+
+static unsigned re_copy_regs(struct re_registers *regs, regmatch_t *pmatch,
+                             Idx nregs, int regs_allocated);
+
+static reg_errcode_t prune_impossible_nodes(re_match_context_t *mctx);
+
+static Idx check_matching(re_match_context_t *mctx, bool fl_longest_match,
+                          Idx *p_match_first);
+
+static Idx check_halt_state_context(const re_match_context_t *mctx,
+                                    const re_dfastate_t *state, Idx idx);
+
+static void update_regs(const re_dfa_t *dfa, regmatch_t *pmatch,
+                        regmatch_t *prev_idx_match, Idx cur_node,
+                        Idx cur_idx, Idx nmatch);
+
+static reg_errcode_t push_fail_stack(struct re_fail_stack_t *fs,
+                                     Idx str_idx, Idx dest_node, Idx nregs,
+                                     regmatch_t *regs,
+                                     re_node_set *eps_via_nodes);
+
+static reg_errcode_t set_regs(const regex_t *preg,
+                              const re_match_context_t *mctx,
+                              size_t nmatch, regmatch_t *pmatch,
+                              bool fl_backtrack);
+
+static reg_errcode_t free_fail_stack_return(struct re_fail_stack_t *fs);
+
+static reg_errcode_t sift_states_backward(const re_match_context_t *mctx,
+                                          re_sift_context_t *sctx);
+
+static reg_errcode_t build_sifted_states(const re_match_context_t *mctx,
+                                         re_sift_context_t *sctx, Idx str_idx,
+                                         re_node_set *cur_dest);
+
+static reg_errcode_t update_cur_sifted_state(const re_match_context_t *mctx,
+                                             re_sift_context_t *sctx,
+                                             Idx str_idx,
+                                             re_node_set *dest_nodes);
+
+static reg_errcode_t add_epsilon_src_nodes(const re_dfa_t *dfa,
+                                           re_node_set *dest_nodes,
+                                           const re_node_set *candidates);
+
+static bool check_dst_limits(const re_match_context_t *mctx,
+                             const re_node_set *limits,
+                             Idx dst_node, Idx dst_idx, Idx src_node,
+                             Idx src_idx);
+
+static int check_dst_limits_calc_pos_1(const re_match_context_t *mctx,
+                                       int boundaries, Idx subexp_idx,
+                                       Idx from_node, Idx bkref_idx);
+
+static int check_dst_limits_calc_pos(const re_match_context_t *mctx,
+                                     Idx limit, Idx subexp_idx,
+                                     Idx node, Idx str_idx,
+                                     Idx bkref_idx);
+
+static reg_errcode_t check_subexp_limits(const re_dfa_t *dfa,
+                                         re_node_set *dest_nodes,
+                                         const re_node_set *candidates,
+                                         re_node_set *limits,
+                                         struct re_backref_cache_entry *bkref_ents,
+                                         Idx str_idx);
+
+static reg_errcode_t sift_states_bkref(const re_match_context_t *mctx,
+                                       re_sift_context_t *sctx,
+                                       Idx str_idx, const re_node_set *candidates);
+
+static reg_errcode_t merge_state_array(const re_dfa_t *dfa,
+                                       re_dfastate_t **dst,
+                                       re_dfastate_t **src, Idx num);
+
+static re_dfastate_t *find_recover_state(reg_errcode_t *err,
+                                         re_match_context_t *mctx);
+
+static re_dfastate_t *transit_state(reg_errcode_t *err,
+                                    re_match_context_t *mctx,
+                                    re_dfastate_t *state);
+
+static re_dfastate_t *merge_state_with_log(reg_errcode_t *err,
+                                           re_match_context_t *mctx,
+                                           re_dfastate_t *next_state);
+
+static reg_errcode_t check_subexp_matching_top(re_match_context_t *mctx,
+                                               re_node_set *cur_nodes,
+                                               Idx str_idx);
+
+static reg_errcode_t transit_state_bkref(re_match_context_t *mctx,
+                                         const re_node_set *nodes);
+
+static reg_errcode_t get_subexp(re_match_context_t *mctx,
+                                Idx bkref_node, Idx bkref_str_idx);
+
+static reg_errcode_t get_subexp_sub(re_match_context_t *mctx,
+                                    const re_sub_match_top_t *sub_top,
+                                    re_sub_match_last_t *sub_last,
+                                    Idx bkref_node, Idx bkref_str);
+
+static Idx find_subexp_node(const re_dfa_t *dfa, const re_node_set *nodes,
+                            Idx subexp_idx, int type);
+
+static reg_errcode_t check_arrival(re_match_context_t *mctx,
+                                   state_array_t *path, Idx top_node,
+                                   Idx top_str, Idx last_node, Idx last_str,
+                                   int type);
+
+static reg_errcode_t check_arrival_add_next_nodes(re_match_context_t *mctx,
+                                                  Idx str_idx,
+                                                  re_node_set *cur_nodes,
+                                                  re_node_set *next_nodes);
+
+static reg_errcode_t check_arrival_expand_ecl(const re_dfa_t *dfa,
+                                              re_node_set *cur_nodes,
+                                              Idx ex_subexp, int type);
+
+static reg_errcode_t check_arrival_expand_ecl_sub(const re_dfa_t *dfa,
+                                                  re_node_set *dst_nodes,
+                                                  Idx target, Idx ex_subexp,
+                                                  int type);
+
+static reg_errcode_t expand_bkref_cache(re_match_context_t *mctx,
+                                        re_node_set *cur_nodes, Idx cur_str,
+                                        Idx subexp_num, int type);
+
+static bool build_trtable(const re_dfa_t *dfa, re_dfastate_t *state);
+
+static Idx group_nodes_into_DFAstates(const re_dfa_t *dfa,
+                                      const re_dfastate_t *state,
+                                      re_node_set *states_node,
+                                      bitset_t *states_ch);
+
+static bool check_node_accept(const re_match_context_t *mctx,
+                              const re_token_t *node, Idx idx);
+
+static reg_errcode_t extend_buffers(re_match_context_t *mctx, int min_len);
+
+/* Check NODE match the current context.  */
+
+static bool
+check_halt_node_context(const re_dfa_t *dfa, Idx node, unsigned int context) {
+    re_token_type_t type = dfa->nodes[node].type;
+    unsigned int constraint = dfa->nodes[node].constraint;
+    if (type != END_OF_RE)
+        return false;
+    if (!constraint)
+        return true;
+    if (NOT_SATISFY_NEXT_CONSTRAINT(constraint, context))
+        return false;
+    return true;
+}
+
+/* Check the halt state STATE match the current context.
+   Return 0 if not match, if the node, STATE has, is a halt node and
+   match the context, return the node.  */
+
+static Idx
+check_halt_state_context(const re_match_context_t *mctx,
+                         const re_dfastate_t *state, Idx idx) {
+    Idx i;
+    unsigned int context;
+    context = re_string_context_at(&mctx->input, idx, mctx->eflags);
+    for (i = 0; i < state->nodes.nelem; ++i)
+        if (check_halt_node_context(mctx->dfa, state->nodes.elems[i], context))
+            return state->nodes.elems[i];
+    return 0;
+}
+
+/* Functions for string operation.  */
+
+/* This function allocate the buffers.  It is necessary to call
+   re_string_reconstruct before using the object.  */
+
+static reg_errcode_t
+
+re_string_allocate(re_string_t *pstr, const char *str, Idx len, Idx init_len,
+                   RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) {
+    reg_errcode_t ret;
+    Idx init_buf_len;
+
+/* Ensure at least one character fits into the buffers.  */
+    if (init_len < dfa->mb_cur_max)
+        init_len = dfa->mb_cur_max;
+    init_buf_len = (len + 1 < init_len) ? len + 1 : init_len;
+    re_string_construct_common(str, len, pstr, trans, icase, dfa);
+
+    ret = re_string_realloc_buffers(pstr, init_buf_len);
+    if ((ret != REG_NOERROR))
+        return ret;
+
+    pstr->word_char = dfa->word_char;
+    pstr->word_ops_used = dfa->word_ops_used;
+    pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+    pstr->valid_len = (pstr->mbs_allocated || dfa->mb_cur_max > 1) ? 0 : len;
+    pstr->valid_raw_len = pstr->valid_len;
+    return REG_NOERROR;
+}
+
+/* This function allocate the buffers, and initialize them.  */
+
+static reg_errcode_t
+
+re_string_construct(re_string_t *pstr, const char *str, Idx len,
+                    RE_TRANSLATE_TYPE trans, bool icase, const re_dfa_t *dfa) {
+    reg_errcode_t ret;
+    memset(pstr, '\0', sizeof(re_string_t));
+    re_string_construct_common(str, len, pstr, trans, icase, dfa);
+
+    if (len > 0) {
+        ret = re_string_realloc_buffers(pstr, len + 1);
+        if ((ret != REG_NOERROR))
+            return ret;
+    }
+    pstr->mbs = pstr->mbs_allocated ? pstr->mbs : (unsigned char *) str;
+
+    if (icase) {
+
+        build_upper_buffer(pstr);
+    } else {
+
+        {
+            if (trans != NULL)
+                re_string_translate_buffer(pstr);
+            else {
+                pstr->valid_len = pstr->bufs_len;
+                pstr->valid_raw_len = pstr->bufs_len;
+            }
+        }
+    }
+
+    return REG_NOERROR;
+}
+
+/* Helper functions for re_string_allocate, and re_string_construct.  */
+
+static reg_errcode_t
+
+re_string_realloc_buffers(re_string_t *pstr, Idx new_buf_len) {
+
+    if (pstr->mbs_allocated) {
+        unsigned char *new_mbs = re_realloc(pstr->mbs,
+        unsigned char,
+        new_buf_len);
+        if ((new_mbs == NULL))
+            return REG_ESPACE;
+        pstr->mbs = new_mbs;
     }
+    pstr->bufs_len = new_buf_len;
+    return REG_NOERROR;
 }
+
+
+static void
+re_string_construct_common(const char *str, Idx len, re_string_t *pstr,
+                           RE_TRANSLATE_TYPE trans, bool icase,
+                           const re_dfa_t *dfa) {
+    pstr->raw_mbs = (const unsigned char *) str;
+    pstr->len = len;
+    pstr->raw_len = len;
+    pstr->trans = trans;
+    pstr->icase = icase;
+    pstr->mbs_allocated = (trans != NULL || icase);
+    pstr->mb_cur_max = dfa->mb_cur_max;
+    pstr->is_utf8 = dfa->is_utf8;
+    pstr->map_notascii = dfa->map_notascii;
+    pstr->stop = pstr->len;
+    pstr->raw_stop = pstr->stop;
+}
+
+/* Build the buffer PSTR->MBS, and apply the translation if we need.
+   This function is used in case of REG_ICASE.  */
+
+static void
+build_upper_buffer(re_string_t *pstr) {
+    Idx char_idx, end_idx;
+    end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+    for (char_idx = pstr->valid_len; char_idx < end_idx; ++char_idx) {
+        int ch = pstr->raw_mbs[pstr->raw_mbs_idx + char_idx];
+        if ((pstr->trans != NULL))
+            ch = pstr->trans[ch];
+        pstr->mbs[char_idx] = toupper(ch);
+    }
+    pstr->valid_len = char_idx;
+    pstr->valid_raw_len = char_idx;
+}
+
+/* Apply TRANS to the buffer in PSTR.  */
+
+static void
+re_string_translate_buffer(re_string_t *pstr) {
+    Idx buf_idx, end_idx;
+    end_idx = (pstr->bufs_len > pstr->len) ? pstr->len : pstr->bufs_len;
+
+    for (buf_idx = pstr->valid_len; buf_idx < end_idx; ++buf_idx) {
+        int ch = pstr->raw_mbs[pstr->raw_mbs_idx + buf_idx];
+        pstr->mbs[buf_idx] = pstr->trans[ch];
+    }
+
+    pstr->valid_len = buf_idx;
+    pstr->valid_raw_len = buf_idx;
+}
+
+/* This function re-construct the buffers.
+   Concretely, convert to wide character in case of pstr->mb_cur_max > 1,
+   convert to upper case in case of REG_ICASE, apply translation.  */
+
+static reg_errcode_t
+
+re_string_reconstruct(re_string_t *pstr, Idx idx, int eflags) {
+    Idx offset;
+
+    if ((pstr->raw_mbs_idx <= idx))
+        offset = idx - pstr->raw_mbs_idx;
+    else {
+/* Reset buffer.  */
+
+        pstr->len = pstr->raw_len;
+        pstr->stop = pstr->raw_stop;
+        pstr->valid_len = 0;
+        pstr->raw_mbs_idx = 0;
+        pstr->valid_raw_len = 0;
+        pstr->offsets_needed = 0;
+        pstr->tip_context = ((eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+                                                   : CONTEXT_NEWLINE | CONTEXT_BEGBUF);
+        if (!pstr->mbs_allocated)
+            pstr->mbs = (unsigned char *) pstr->raw_mbs;
+        offset = idx;
+    }
+
+    if ((offset != 0)) {
+/* Should the already checked characters be kept?  */
+        if ((offset < pstr->valid_raw_len)) {
+/* Yes, move them to the front of the buffer.  */
+
+            {
+                pstr->tip_context = re_string_context_at(pstr, offset - 1,
+                                                         eflags);
+
+                if ((pstr->mbs_allocated))
+                    memmove(pstr->mbs, pstr->mbs + offset,
+                            pstr->valid_len - offset);
+                pstr->valid_len -= offset;
+                pstr->valid_raw_len -= offset;
+
+            }
+        } else {
+
+            pstr->valid_len = 0;
+
+            {
+                int c = pstr->raw_mbs[pstr->raw_mbs_idx + offset - 1];
+                pstr->valid_raw_len = 0;
+                if (pstr->trans)
+                    c = pstr->trans[c];
+                pstr->tip_context = (bitset_contain(pstr->word_char, c)
+                                     ? CONTEXT_WORD
+                                     : ((IS_NEWLINE(c) && pstr->newline_anchor)
+                                        ? CONTEXT_NEWLINE : 0));
+            }
+        }
+        if (!(pstr->mbs_allocated))
+            pstr->mbs += offset;
+    }
+    pstr->raw_mbs_idx = idx;
+    pstr->len -= offset;
+    pstr->stop -= offset;
+
+/* Then build the buffers.  */
+
+    if ((pstr->mbs_allocated)) {
+        if (pstr->icase)
+            build_upper_buffer(pstr);
+        else if (pstr->trans != NULL)
+            re_string_translate_buffer(pstr);
+    } else
+        pstr->valid_len = pstr->len;
+
+    pstr->cur_idx = 0;
+    return REG_NOERROR;
+}
+
+static unsigned char
+__attribute__ ((pure))
+re_string_peek_byte_case(const re_string_t *pstr, Idx idx) {
+    int ch;
+    Idx off;
+
+    /* Handle the common (easiest) cases first.  */
+    if ((!pstr->mbs_allocated))
+        return re_string_peek_byte(pstr, idx);
+
+    off = pstr->cur_idx + idx;
+
+    ch = pstr->raw_mbs[pstr->raw_mbs_idx + off];
+
+    return ch;
+}
+
+static unsigned char
+re_string_fetch_byte_case(re_string_t *pstr) {
+    if ((!pstr->mbs_allocated))
+        return re_string_fetch_byte(pstr);
+
+    return pstr->raw_mbs[pstr->raw_mbs_idx + pstr->cur_idx++];
+}
+
+static void
+re_string_destruct(re_string_t *pstr) {
+
+    if (pstr->mbs_allocated)
+        re_free(pstr->mbs);
+}
+
+/* Return the context at IDX in INPUT.  */
+
+static unsigned int
+re_string_context_at(const re_string_t *input, Idx idx, int eflags) {
+    int c;
+    if ((idx < 0))
+        /* In this case, we use the value stored in input->tip_context,
+           since we can't know the character in input->mbs[-1] here.  */
+        return input->tip_context;
+    if ((idx == input->len))
+        return ((eflags & REG_NOTEOL) ? CONTEXT_ENDBUF
+                                      : CONTEXT_NEWLINE | CONTEXT_ENDBUF);
+
+    {
+        c = re_string_byte_at(input, idx);
+        if (bitset_contain(input->word_char, c))
+            return CONTEXT_WORD;
+        return IS_NEWLINE(c) && input->newline_anchor ? CONTEXT_NEWLINE : 0;
+    }
+}
+
+/* Functions for set operation.  */
+
+static reg_errcode_t
+
+re_node_set_alloc(re_node_set *set, Idx size) {
+    set->alloc = size;
+    set->nelem = 0;
+    set->elems = re_malloc(Idx, size);
+    if ((set->elems == NULL)
+        && (MALLOC_0_IS_NONNULL || size != 0))
+        return REG_ESPACE;
+    return REG_NOERROR;
+}
+
+static reg_errcode_t
+
+re_node_set_init_1(re_node_set *set, Idx elem) {
+    set->alloc = 1;
+    set->nelem = 1;
+    set->elems = re_malloc(Idx, 1);
+    if ((set->elems == NULL)) {
+        set->alloc = set->nelem = 0;
+        return REG_ESPACE;
+    }
+    set->elems[0] = elem;
+    return REG_NOERROR;
+}
+
+static reg_errcode_t
+
+re_node_set_init_2(re_node_set *set, Idx elem1, Idx elem2) {
+    set->alloc = 2;
+    set->elems = re_malloc(Idx, 2);
+    if ((set->elems == NULL))
+        return REG_ESPACE;
+    if (elem1 == elem2) {
+        set->nelem = 1;
+        set->elems[0] = elem1;
+    } else {
+        set->nelem = 2;
+        if (elem1 < elem2) {
+            set->elems[0] = elem1;
+            set->elems[1] = elem2;
+        } else {
+            set->elems[0] = elem2;
+            set->elems[1] = elem1;
+        }
+    }
+    return REG_NOERROR;
+}
+
+static reg_errcode_t
+
+re_node_set_init_copy(re_node_set *dest, const re_node_set *src) {
+    dest->nelem = src->nelem;
+    if (src->nelem > 0) {
+        dest->alloc = dest->nelem;
+        dest->elems = re_malloc(Idx, dest->alloc);
+        if ((dest->elems == NULL)) {
+            dest->alloc = dest->nelem = 0;
+            return REG_ESPACE;
+        }
+        memcpy(dest->elems, src->elems, src->nelem * sizeof(Idx));
+    } else
+        re_node_set_init_empty(dest);
+    return REG_NOERROR;
+}
+
+/* Calculate the intersection of the sets SRC1 and SRC2. And merge it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.
+   Note: We assume dest->elems is NULL, when dest->alloc is 0.  */
+
+static reg_errcode_t
+
+re_node_set_add_intersect(re_node_set *dest, const re_node_set *src1,
+                          const re_node_set *src2) {
+    Idx i1, i2, is, id, delta, sbase;
+    if (src1->nelem == 0 || src2->nelem == 0)
+        return REG_NOERROR;
+
+/* We need dest->nelem + 2 * elems_in_intersection; this is a
+   conservative estimate.  */
+    if (src1->nelem + src2->nelem + dest->nelem > dest->alloc) {
+        Idx new_alloc = src1->nelem + src2->nelem + dest->alloc;
+        Idx *new_elems = re_realloc(dest->elems, Idx, new_alloc);
+        if ((new_elems == NULL))
+            return REG_ESPACE;
+        dest->elems = new_elems;
+        dest->alloc = new_alloc;
+    }
+
+/* Find the items in the intersection of SRC1 and SRC2, and copy
+   into the top of DEST those that are not already in DEST itself.  */
+    sbase = dest->nelem + src1->nelem + src2->nelem;
+    i1 = src1->nelem - 1;
+    i2 = src2->nelem - 1;
+    id = dest->nelem - 1;
+    for (;;) {
+        if (src1->elems[i1] == src2->elems[i2]) {
+/* Try to find the item in DEST.  Maybe we could binary search?  */
+            while (id >= 0 && dest->elems[id] > src1->elems[i1])
+                --id;
+
+            if (id < 0 || dest->elems[id] != src1->elems[i1])
+                dest->elems[--sbase] = src1->elems[i1];
+
+            if (--i1 < 0 || --i2 < 0)
+                break;
+        }
+
+/* Lower the highest of the two items.  */
+        else if (src1->elems[i1] < src2->elems[i2]) {
+            if (--i2 < 0)
+                break;
+        } else {
+            if (--i1 < 0)
+                break;
+        }
+    }
+
+    id = dest->nelem - 1;
+    is = dest->nelem + src1->nelem + src2->nelem - 1;
+    delta = is - sbase + 1;
+
+/* Now copy.  When DELTA becomes zero, the remaining
+   DEST elements are already in place; this is more or
+   less the same loop that is in re_node_set_merge.  */
+    dest->nelem += delta;
+    if (delta > 0 && id >= 0)
+        for (;;) {
+            if (dest->elems[is] > dest->elems[id]) {
+/* Copy from the top.  */
+                dest->elems[id + delta--] = dest->elems[is--];
+                if (delta == 0)
+                    break;
+            } else {
+/* Slide from the bottom.  */
+                dest->elems[id + delta] = dest->elems[id];
+                if (--id < 0)
+                    break;
+            }
+        }
+
+/* Copy remaining SRC elements.  */
+    memcpy(dest->elems, dest->elems + sbase, delta * sizeof(Idx));
+
+    return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets SRC1 and SRC2. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+
+re_node_set_init_union(re_node_set *dest, const re_node_set *src1,
+                       const re_node_set *src2) {
+    Idx i1, i2, id;
+    if (src1 != NULL && src1->nelem > 0 && src2 != NULL && src2->nelem > 0) {
+        dest->alloc = src1->nelem + src2->nelem;
+        dest->elems = re_malloc(Idx, dest->alloc);
+        if ((dest->elems == NULL))
+            return REG_ESPACE;
+    } else {
+        if (src1 != NULL && src1->nelem > 0)
+            return re_node_set_init_copy(dest, src1);
+        else if (src2 != NULL && src2->nelem > 0)
+            return re_node_set_init_copy(dest, src2);
+        else
+            re_node_set_init_empty(dest);
+        return REG_NOERROR;
+    }
+    for (i1 = i2 = id = 0; i1 < src1->nelem && i2 < src2->nelem;) {
+        if (src1->elems[i1] > src2->elems[i2]) {
+            dest->elems[id++] = src2->elems[i2++];
+            continue;
+        }
+        if (src1->elems[i1] == src2->elems[i2])
+            ++i2;
+        dest->elems[id++] = src1->elems[i1++];
+    }
+    if (i1 < src1->nelem) {
+        memcpy(dest->elems + id, src1->elems + i1,
+               (src1->nelem - i1) * sizeof(Idx));
+        id += src1->nelem - i1;
+    } else if (i2 < src2->nelem) {
+        memcpy(dest->elems + id, src2->elems + i2,
+               (src2->nelem - i2) * sizeof(Idx));
+        id += src2->nelem - i2;
+    }
+    dest->nelem = id;
+    return REG_NOERROR;
+}
+
+/* Calculate the union set of the sets DEST and SRC. And store it to
+   DEST. Return value indicate the error code or REG_NOERROR if succeeded.  */
+
+static reg_errcode_t
+
+re_node_set_merge(re_node_set *dest, const re_node_set *src) {
+    Idx is, id, sbase, delta;
+    if (src == NULL || src->nelem == 0)
+        return REG_NOERROR;
+    if (dest->alloc < 2 * src->nelem + dest->nelem) {
+        Idx new_alloc = 2 * (src->nelem + dest->alloc);
+        Idx *new_buffer = re_realloc(dest->elems, Idx, new_alloc);
+        if ((new_buffer == NULL))
+            return REG_ESPACE;
+        dest->elems = new_buffer;
+        dest->alloc = new_alloc;
+    }
+
+    if ((dest->nelem == 0)) {
+        dest->nelem = src->nelem;
+        memcpy(dest->elems, src->elems, src->nelem * sizeof(Idx));
+        return REG_NOERROR;
+    }
+
+/* Copy into the top of DEST the items of SRC that are not
+   found in DEST.  Maybe we could binary search in DEST?  */
+    for (sbase = dest->nelem + 2 * src->nelem,
+         is = src->nelem - 1, id = dest->nelem - 1; is >= 0 && id >= 0;) {
+        if (dest->elems[id] == src->elems[is])
+            is--, id--;
+        else if (dest->elems[id] < src->elems[is])
+            dest->elems[--sbase] = src->elems[is--];
+        else /* if (dest->elems[id] > src->elems[is]) */
+            --id;
+    }
+
+    if (is >= 0) {
+/* If DEST is exhausted, the remaining items of SRC must be unique.  */
+        sbase -= is + 1;
+        memcpy(dest->elems + sbase, src->elems, (is + 1) * sizeof(Idx));
+    }
+
+    id = dest->nelem - 1;
+    is = dest->nelem + 2 * src->nelem - 1;
+    delta = is - sbase + 1;
+    if (delta == 0)
+        return REG_NOERROR;
+
+/* Now copy.  When DELTA becomes zero, the remaining
+   DEST elements are already in place.  */
+    dest->nelem += delta;
+    for (;;) {
+        if (dest->elems[is] > dest->elems[id]) {
+/* Copy from the top.  */
+            dest->elems[id + delta--] = dest->elems[is--];
+            if (delta == 0)
+                break;
+        } else {
+/* Slide from the bottom.  */
+            dest->elems[id + delta] = dest->elems[id];
+            if (--id < 0) {
+/* Copy remaining SRC elements.  */
+                memcpy(dest->elems, dest->elems + sbase,
+                       delta * sizeof(Idx));
+                break;
+            }
+        }
+    }
+
+    return REG_NOERROR;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have ELEM.
+   Return true if successful.  */
+
+static bool
+
+re_node_set_insert(re_node_set *set, Idx elem) {
+    Idx idx;
+/* In case the set is empty.  */
+    if (set->alloc == 0)
+        return (re_node_set_init_1(set, elem) == REG_NOERROR);
+
+    if ((set->nelem) == 0) {
+/* We already guaranteed above that set->alloc != 0.  */
+        set->elems[0] = elem;
+        ++set->nelem;
+        return true;
+    }
+
+/* Realloc if we need.  */
+    if (set->alloc == set->nelem) {
+        Idx *new_elems;
+        set->alloc = set->alloc * 2;
+        new_elems = re_realloc(set->elems, Idx, set->alloc);
+        if ((new_elems == NULL))
+            return false;
+        set->elems = new_elems;
+    }
+
+/* Move the elements which follows the new element.  Test the
+   first element separately to skip a check in the inner loop.  */
+    if (elem < set->elems[0]) {
+        idx = 0;
+        for (idx = set->nelem; idx > 0; idx--)
+            set->elems[idx] = set->elems[idx - 1];
+    } else {
+        for (idx = set->nelem; set->elems[idx - 1] > elem; idx--)
+            set->elems[idx] = set->elems[idx - 1];
+    }
+
+/* Insert the new element.  */
+    set->elems[idx] = elem;
+    ++set->nelem;
+    return true;
+}
+
+/* Insert the new element ELEM to the re_node_set* SET.
+   SET should not already have any element greater than or equal to ELEM.
+   Return true if successful.  */
+
+static bool
+
+re_node_set_insert_last(re_node_set *set, Idx elem) {
+/* Realloc if we need.  */
+    if (set->alloc == set->nelem) {
+        Idx *new_elems;
+        set->alloc = (set->alloc + 1) * 2;
+        new_elems = re_realloc(set->elems, Idx, set->alloc);
+        if ((new_elems == NULL))
+            return false;
+        set->elems = new_elems;
+    }
+
+/* Insert the new element.  */
+    set->elems[set->nelem++] = elem;
+    return true;
+}
+
+/* Compare two node sets SET1 and SET2.
+   Return true if SET1 and SET2 are equivalent.  */
+
+static bool
+__attribute__ ((pure))
+re_node_set_compare(const re_node_set *set1, const re_node_set *set2) {
+    Idx i;
+    if (set1 == NULL || set2 == NULL || set1->nelem != set2->nelem)
+        return false;
+    for (i = set1->nelem; --i >= 0;)
+        if (set1->elems[i] != set2->elems[i])
+            return false;
+    return true;
+}
+
+/* Return (idx + 1) if SET contains the element ELEM, return 0 otherwise.  */
+
+static Idx
+__attribute__ ((pure))
+re_node_set_contains(const re_node_set *set, Idx elem) {
+    __re_size_t idx, right, mid;
+    if (set->nelem <= 0)
+        return 0;
+
+    /* Binary search the element.  */
+    idx = 0;
+    right = set->nelem - 1;
+    while (idx < right) {
+        mid = (idx + right) / 2;
+        if (set->elems[mid] < elem)
+            idx = mid + 1;
+        else
+            right = mid;
+    }
+    return set->elems[idx] == elem ? idx + 1 : 0;
+}
+
+static void
+re_node_set_remove_at(re_node_set *set, Idx idx) {
+    if (idx < 0 || idx >= set->nelem)
+        return;
+    --set->nelem;
+    for (; idx < set->nelem; idx++)
+        set->elems[idx] = set->elems[idx + 1];
+}
+
+
+/* Add the token TOKEN to dfa->nodes, and return the index of the token.
+   Or return -1 if an error occurred.  */
+
+static Idx
+re_dfa_add_node(re_dfa_t *dfa, re_token_t token) {
+    if ((dfa->nodes_len >= dfa->nodes_alloc)) {
+        size_t new_nodes_alloc = dfa->nodes_alloc * 2;
+        Idx *new_nexts, *new_indices;
+        re_node_set *new_edests, *new_eclosures;
+        re_token_t *new_nodes;
+
+        /* Avoid overflows in realloc.  */
+        const size_t max_object_size = MAX (sizeof(re_token_t),
+                                            MAX(sizeof(re_node_set),
+                                                sizeof(Idx)));
+        if ((MIN (IDX_MAX, SIZE_MAX / max_object_size)
+             < new_nodes_alloc))
+            return -1;
+
+        new_nodes = re_realloc(dfa->nodes, re_token_t, new_nodes_alloc);
+        if ((new_nodes == NULL))
+            return -1;
+        dfa->nodes = new_nodes;
+        new_nexts = re_realloc(dfa->nexts, Idx, new_nodes_alloc);
+        new_indices = re_realloc(dfa->org_indices, Idx, new_nodes_alloc);
+        new_edests = re_realloc(dfa->edests, re_node_set, new_nodes_alloc);
+        new_eclosures = re_realloc(dfa->eclosures, re_node_set, new_nodes_alloc);
+        if ((new_nexts == NULL || new_indices == NULL
+             || new_edests == NULL || new_eclosures == NULL)) {
+            re_free(new_nexts);
+            re_free(new_indices);
+            re_free(new_edests);
+            re_free(new_eclosures);
+            return -1;
+        }
+        dfa->nexts = new_nexts;
+        dfa->org_indices = new_indices;
+        dfa->edests = new_edests;
+        dfa->eclosures = new_eclosures;
+        dfa->nodes_alloc = new_nodes_alloc;
+    }
+    dfa->nodes[dfa->nodes_len] = token;
+    dfa->nodes[dfa->nodes_len].constraint = 0;
+    dfa->nexts[dfa->nodes_len] = -1;
+    re_node_set_init_empty(dfa->edests + dfa->nodes_len);
+    re_node_set_init_empty(dfa->eclosures + dfa->nodes_len);
+    return dfa->nodes_len++;
+}
+
+static re_hashval_t
+calc_state_hash(const re_node_set *nodes, unsigned int context) {
+    re_hashval_t hash = nodes->nelem + context;
+    Idx i;
+    for (i = 0; i < nodes->nelem; i++)
+        hash += nodes->elems[i];
+    return hash;
+}
+
+/* Search for the state whose node_set is equivalent to NODES.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+	   return value is NULL and ERR is REG_NOERROR.
+	 - We never return non-NULL value in case of any errors, it is for
+	   optimization.  */
+
+static re_dfastate_t *
+
+re_acquire_state(reg_errcode_t *err, const re_dfa_t *dfa,
+                 const re_node_set *nodes) {
+    re_hashval_t hash;
+    re_dfastate_t *new_state;
+    struct re_state_table_entry *spot;
+    Idx i;
+#if defined GCC_LINT || defined lint
+                                                                                                                            /* Suppress bogus uninitialized-variable warnings.  */
+  *err = REG_NOERROR;
+#endif
+    if ((nodes->nelem == 0)) {
+        *err = REG_NOERROR;
+        return NULL;
+    }
+    hash = calc_state_hash(nodes, 0);
+    spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+    for (i = 0; i < spot->num; i++) {
+        re_dfastate_t *state = spot->array[i];
+        if (hash != state->hash)
+            continue;
+        if (re_node_set_compare(&state->nodes, nodes))
+            return state;
+    }
+
+/* There are no appropriate state in the dfa, create the new one.  */
+    new_state = create_ci_newstate(dfa, nodes, hash);
+    if ((new_state == NULL))
+        *err = REG_ESPACE;
+
+    return new_state;
+}
+
+/* Search for the state whose node_set is equivalent to NODES and
+   whose context is equivalent to CONTEXT.
+   Return the pointer to the state, if we found it in the DFA.
+   Otherwise create the new one and return it.  In case of an error
+   return NULL and set the error code in ERR.
+   Note: - We assume NULL as the invalid state, then it is possible that
+	   return value is NULL and ERR is REG_NOERROR.
+	 - We never return non-NULL value in case of any errors, it is for
+	   optimization.  */
+
+static re_dfastate_t *
+
+re_acquire_state_context(reg_errcode_t *err, const re_dfa_t *dfa,
+                         const re_node_set *nodes, unsigned int context) {
+    re_hashval_t hash;
+    re_dfastate_t *new_state;
+    struct re_state_table_entry *spot;
+    Idx i;
+#if defined GCC_LINT || defined lint
+                                                                                                                            /* Suppress bogus uninitialized-variable warnings.  */
+  *err = REG_NOERROR;
+#endif
+    if (nodes->nelem == 0) {
+        *err = REG_NOERROR;
+        return NULL;
+    }
+    hash = calc_state_hash(nodes, context);
+    spot = dfa->state_table + (hash & dfa->state_hash_mask);
+
+    for (i = 0; i < spot->num; i++) {
+        re_dfastate_t *state = spot->array[i];
+        if (state->hash == hash
+            && state->context == context
+            && re_node_set_compare(state->entrance_nodes, nodes))
+            return state;
+    }
+/* There are no appropriate state in 'dfa', create the new one.  */
+    new_state = create_cd_newstate(dfa, nodes, context, hash);
+    if ((new_state == NULL))
+        *err = REG_ESPACE;
+
+    return new_state;
+}
+
+/* Finish initialization of the new state NEWSTATE, and using its hash value
+   HASH put in the appropriate bucket of DFA's state table.  Return value
+   indicates the error code if failed.  */
+
+static reg_errcode_t
+
+register_state(const re_dfa_t *dfa, re_dfastate_t *newstate,
+               re_hashval_t hash) {
+    struct re_state_table_entry *spot;
+    reg_errcode_t err;
+    Idx i;
+
+    newstate->hash = hash;
+    err = re_node_set_alloc(&newstate->non_eps_nodes, newstate->nodes.nelem);
+    if ((err != REG_NOERROR))
+        return REG_ESPACE;
+    for (i = 0; i < newstate->nodes.nelem; i++) {
+        Idx elem = newstate->nodes.elems[i];
+        if (!IS_EPSILON_NODE(dfa->nodes[elem].type))
+            if (!re_node_set_insert_last(&newstate->non_eps_nodes, elem))
+                return REG_ESPACE;
+    }
+
+    spot = dfa->state_table + (hash & dfa->state_hash_mask);
+    if ((spot->alloc <= spot->num)) {
+        Idx new_alloc = 2 * spot->num + 2;
+        re_dfastate_t **new_array = re_realloc(spot->array, re_dfastate_t * ,
+                                               new_alloc);
+        if ((new_array == NULL))
+            return REG_ESPACE;
+        spot->array = new_array;
+        spot->alloc = new_alloc;
+    }
+    spot->array[spot->num++] = newstate;
+    return REG_NOERROR;
+}
+
+static void
+free_state(re_dfastate_t *state) {
+    re_node_set_free(&state->non_eps_nodes);
+    re_node_set_free(&state->inveclosure);
+    if (state->entrance_nodes != &state->nodes) {
+        re_node_set_free(state->entrance_nodes);
+        re_free(state->entrance_nodes);
+    }
+    re_node_set_free(&state->nodes);
+    re_free(state->word_trtable);
+    re_free(state->trtable);
+    re_free(state);
+}
+
+/* Create the new state which is independent of contexts.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+
+create_ci_newstate(const re_dfa_t *dfa, const re_node_set *nodes,
+                   re_hashval_t hash) {
+    Idx i;
+    reg_errcode_t err;
+    re_dfastate_t *newstate;
+
+    newstate = (re_dfastate_t *) calloc(sizeof(re_dfastate_t), 1);
+    if ((newstate == NULL))
+        return NULL;
+    err = re_node_set_init_copy(&newstate->nodes, nodes);
+    if ((err != REG_NOERROR)) {
+        re_free(newstate);
+        return NULL;
+    }
+
+    newstate->entrance_nodes = &newstate->nodes;
+    for (i = 0; i < nodes->nelem; i++) {
+        re_token_t *node = dfa->nodes + nodes->elems[i];
+        re_token_type_t type = node->type;
+        if (type == CHARACTER && !node->constraint)
+            continue;
+
+        /* If the state has the halt node, the state is a halt state.  */
+        if (type == END_OF_RE)
+            newstate->halt = 1;
+        else if (type == OP_BACK_REF)
+            newstate->has_backref = 1;
+        else if (type == ANCHOR || node->constraint)
+            newstate->has_constraint = 1;
+    }
+    err = register_state(dfa, newstate, hash);
+    if ((err != REG_NOERROR)) {
+        free_state(newstate);
+        newstate = NULL;
+    }
+    return newstate;
+}
+
+/* Create the new state which is depend on the context CONTEXT.
+   Return the new state if succeeded, otherwise return NULL.  */
+
+static re_dfastate_t *
+
+create_cd_newstate(const re_dfa_t *dfa, const re_node_set *nodes,
+                   unsigned int context, re_hashval_t hash) {
+    Idx i, nctx_nodes = 0;
+    reg_errcode_t err;
+    re_dfastate_t *newstate;
+
+    newstate = (re_dfastate_t *) calloc(sizeof(re_dfastate_t), 1);
+    if ((newstate == NULL))
+        return NULL;
+    err = re_node_set_init_copy(&newstate->nodes, nodes);
+    if ((err != REG_NOERROR)) {
+        re_free(newstate);
+        return NULL;
+    }
+
+    newstate->context = context;
+    newstate->entrance_nodes = &newstate->nodes;
+
+    for (i = 0; i < nodes->nelem; i++) {
+        re_token_t *node = dfa->nodes + nodes->elems[i];
+        re_token_type_t type = node->type;
+        unsigned int constraint = node->constraint;
+
+        if (type == CHARACTER && !constraint)
+            continue;
+
+        /* If the state has the halt node, the state is a halt state.  */
+        if (type == END_OF_RE)
+            newstate->halt = 1;
+        else if (type == OP_BACK_REF)
+            newstate->has_backref = 1;
+
+        if (constraint) {
+            if (newstate->entrance_nodes == &newstate->nodes) {
+                newstate->entrance_nodes = re_malloc(re_node_set, 1);
+                if ((newstate->entrance_nodes == NULL)) {
+                    free_state(newstate);
+                    return NULL;
+                }
+                if (re_node_set_init_copy(newstate->entrance_nodes, nodes)
+                    != REG_NOERROR)
+                    return NULL;
+                nctx_nodes = 0;
+                newstate->has_constraint = 1;
+            }
+
+            if (NOT_SATISFY_PREV_CONSTRAINT(constraint, context)) {
+                re_node_set_remove_at(&newstate->nodes, i - nctx_nodes);
+                ++nctx_nodes;
+            }
+        }
+    }
+    err = register_state(dfa, newstate, hash);
+    if ((err != REG_NOERROR)) {
+        free_state(newstate);
+        newstate = NULL;
+    }
+    return newstate;
+}
+
+/* Extended regular expression matching and search library.
+   Copyright (C) 2002-2018 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+   Contributed by Isamu Hasegawa <isamu@yamato.ibm.com>.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <https://www.gnu.org/licenses/>.  */
+
+#ifndef RE_TRANSLATE_TYPE
+# define __RE_TRANSLATE_TYPE unsigned char *
+# ifdef __USE_GNU
+#  define RE_TRANSLATE_TYPE __RE_TRANSLATE_TYPE
+# endif
+#endif
+
+# define __REPB_PREFIX(name) name
+
+
+static reg_errcode_t re_compile_internal(regex_t *preg, const char *pattern,
+                                         size_t length, reg_syntax_t syntax);
+
+static void re_compile_fastmap_iter(regex_t *bufp,
+                                    const re_dfastate_t *init_state,
+                                    char *fastmap);
+
+static reg_errcode_t init_dfa(re_dfa_t *dfa, size_t pat_len);
+
+static void free_workarea_compile(regex_t *preg);
+
+static reg_errcode_t create_initial_state(re_dfa_t *dfa);
+
+static reg_errcode_t analyze(regex_t *preg);
+
+static reg_errcode_t preorder(bin_tree_t *root,
+                              reg_errcode_t (fn(void *, bin_tree_t *)),
+                              void *extra);
+
+static reg_errcode_t postorder(bin_tree_t *root,
+                               reg_errcode_t (fn(void *, bin_tree_t *)),
+                               void *extra);
+
+static reg_errcode_t optimize_subexps(void *extra, bin_tree_t *node);
+
+static reg_errcode_t lower_subexps(void *extra, bin_tree_t *node);
+
+static bin_tree_t *lower_subexp(reg_errcode_t *err, regex_t *preg,
+                                bin_tree_t *node);
+
+static reg_errcode_t calc_first(void *extra, bin_tree_t *node);
+
+static reg_errcode_t calc_next(void *extra, bin_tree_t *node);
+
+static reg_errcode_t link_nfa_nodes(void *extra, bin_tree_t *node);
+
+static Idx duplicate_node(re_dfa_t *dfa, Idx org_idx, unsigned int constraint);
+
+static Idx search_duplicated_node(const re_dfa_t *dfa, Idx org_node,
+                                  unsigned int constraint);
+
+static reg_errcode_t calc_eclosure(re_dfa_t *dfa);
+
+static reg_errcode_t calc_eclosure_iter(re_node_set *new_set, re_dfa_t *dfa,
+                                        Idx node, bool root);
+
+static reg_errcode_t calc_inveclosure(re_dfa_t *dfa);
+
+static Idx fetch_number(re_string_t *input, re_token_t *token,
+                        reg_syntax_t syntax);
+
+static int peek_token(re_token_t *token, re_string_t *input,
+                      reg_syntax_t syntax);
+
+static bin_tree_t *parse(re_string_t *regexp, regex_t *preg,
+                         reg_syntax_t syntax, reg_errcode_t *err);
+
+static bin_tree_t *parse_reg_exp(re_string_t *regexp, regex_t *preg,
+                                 re_token_t *token, reg_syntax_t syntax,
+                                 Idx nest, reg_errcode_t *err);
+
+static bin_tree_t *parse_branch(re_string_t *regexp, regex_t *preg,
+                                re_token_t *token, reg_syntax_t syntax,
+                                Idx nest, reg_errcode_t *err);
+
+static bin_tree_t *parse_expression(re_string_t *regexp, regex_t *preg,
+                                    re_token_t *token, reg_syntax_t syntax,
+                                    Idx nest, reg_errcode_t *err);
+
+static bin_tree_t *parse_sub_exp(re_string_t *regexp, regex_t *preg,
+                                 re_token_t *token, reg_syntax_t syntax,
+                                 Idx nest, reg_errcode_t *err);
+
+static bin_tree_t *parse_dup_op(bin_tree_t *dup_elem, re_string_t *regexp,
+                                re_dfa_t *dfa, re_token_t *token,
+                                reg_syntax_t syntax, reg_errcode_t *err);
+
+static bin_tree_t *parse_bracket_exp(re_string_t *regexp, re_dfa_t *dfa,
+                                     re_token_t *token, reg_syntax_t syntax,
+                                     reg_errcode_t *err);
+
+static reg_errcode_t parse_bracket_element(bracket_elem_t *elem,
+                                           re_string_t *regexp,
+                                           re_token_t *token, int token_len,
+                                           re_dfa_t *dfa,
+                                           reg_syntax_t syntax,
+                                           bool accept_hyphen);
+
+static reg_errcode_t parse_bracket_symbol(bracket_elem_t *elem,
+                                          re_string_t *regexp,
+                                          re_token_t *token);
+
+static reg_errcode_t build_equiv_class(bitset_t sbcset,
+                                       const unsigned char *name);
+
+static reg_errcode_t build_charclass(RE_TRANSLATE_TYPE trans,
+                                     bitset_t sbcset,
+                                     const char *class_name,
+                                     reg_syntax_t syntax);
+
+static bin_tree_t *build_charclass_op(re_dfa_t *dfa,
+                                      RE_TRANSLATE_TYPE trans,
+                                      const char *class_name,
+                                      const char *extra,
+                                      bool non_match, reg_errcode_t *err);
+
+static bin_tree_t *create_tree(re_dfa_t *dfa,
+                               bin_tree_t *left, bin_tree_t *right,
+                               re_token_type_t type);
+
+static bin_tree_t *create_token_tree(re_dfa_t *dfa,
+                                     bin_tree_t *left, bin_tree_t *right,
+                                     const re_token_t *token);
+
+static bin_tree_t *duplicate_tree(const bin_tree_t *src, re_dfa_t *dfa);
+
+static void free_token(re_token_t *node);
+
+static reg_errcode_t free_tree(void *extra, bin_tree_t *node);
+
+static reg_errcode_t mark_opt_subexp(void *extra, bin_tree_t *node);
+
+/* This table gives an error message for each of the error codes listed
+   in regex.h.  Obviously the order here has to be same as there.
+   POSIX doesn't require that we do anything for REG_NOERROR,
+   but why not be nice?  */
+
+static const char __re_error_msgid[] =
+        {
+#define REG_NOERROR_IDX    0
+                gettext_noop("Success")    /* REG_NOERROR */
+                "\0"
+#define REG_NOMATCH_IDX (REG_NOERROR_IDX + sizeof "Success")
+                gettext_noop ("No match")    /* REG_NOMATCH */
+                "\0"
+#define REG_BADPAT_IDX    (REG_NOMATCH_IDX + sizeof "No match")
+                gettext_noop ("Invalid regular expression") /* REG_BADPAT */
+                "\0"
+#define REG_ECOLLATE_IDX (REG_BADPAT_IDX + sizeof "Invalid regular expression")
+                gettext_noop ("Invalid collation character") /* REG_ECOLLATE */
+                "\0"
+#define REG_ECTYPE_IDX    (REG_ECOLLATE_IDX + sizeof "Invalid collation character")
+                gettext_noop ("Invalid character class name") /* REG_ECTYPE */
+                "\0"
+#define REG_EESCAPE_IDX    (REG_ECTYPE_IDX + sizeof "Invalid character class name")
+                gettext_noop ("Trailing backslash") /* REG_EESCAPE */
+                "\0"
+#define REG_ESUBREG_IDX    (REG_EESCAPE_IDX + sizeof "Trailing backslash")
+                gettext_noop ("Invalid back reference") /* REG_ESUBREG */
+                "\0"
+#define REG_EBRACK_IDX    (REG_ESUBREG_IDX + sizeof "Invalid back reference")
+                gettext_noop ("Unmatched [, [^, [:, [., or [=")    /* REG_EBRACK */
+                "\0"
+#define REG_EPAREN_IDX    (REG_EBRACK_IDX + sizeof "Unmatched [, [^, [:, [., or [=")
+                gettext_noop ("Unmatched ( or \\(") /* REG_EPAREN */
+                "\0"
+#define REG_EBRACE_IDX    (REG_EPAREN_IDX + sizeof "Unmatched ( or \\(")
+                gettext_noop ("Unmatched \\{") /* REG_EBRACE */
+                "\0"
+#define REG_BADBR_IDX    (REG_EBRACE_IDX + sizeof "Unmatched \\{")
+                gettext_noop ("Invalid content of \\{\\}") /* REG_BADBR */
+                "\0"
+#define REG_ERANGE_IDX    (REG_BADBR_IDX + sizeof "Invalid content of \\{\\}")
+                gettext_noop ("Invalid range end")    /* REG_ERANGE */
+                "\0"
+#define REG_ESPACE_IDX    (REG_ERANGE_IDX + sizeof "Invalid range end")
+                gettext_noop ("Memory exhausted") /* REG_ESPACE */
+                "\0"
+#define REG_BADRPT_IDX    (REG_ESPACE_IDX + sizeof "Memory exhausted")
+                gettext_noop ("Invalid preceding regular expression") /* REG_BADRPT */
+                "\0"
+#define REG_EEND_IDX    (REG_BADRPT_IDX + sizeof "Invalid preceding regular expression")
+                gettext_noop ("Premature end of regular expression") /* REG_EEND */
+                "\0"
+#define REG_ESIZE_IDX    (REG_EEND_IDX + sizeof "Premature end of regular expression")
+                gettext_noop ("Regular expression too big") /* REG_ESIZE */
+                "\0"
+#define REG_ERPAREN_IDX    (REG_ESIZE_IDX + sizeof "Regular expression too big")
+                gettext_noop ("Unmatched ) or \\)") /* REG_ERPAREN */
+        };
+
+static const size_t __re_error_msgid_idx[] =
+        {
+                REG_NOERROR_IDX,
+                REG_NOMATCH_IDX,
+                REG_BADPAT_IDX,
+                REG_ECOLLATE_IDX,
+                REG_ECTYPE_IDX,
+                REG_EESCAPE_IDX,
+                REG_ESUBREG_IDX,
+                REG_EBRACK_IDX,
+                REG_EPAREN_IDX,
+                REG_EBRACE_IDX,
+                REG_BADBR_IDX,
+                REG_ERANGE_IDX,
+                REG_ESPACE_IDX,
+                REG_BADRPT_IDX,
+                REG_EEND_IDX,
+                REG_ESIZE_IDX,
+                REG_ERPAREN_IDX
+        };
+
+/* Entry points for GNU code.  */
+
+/* re_compile_pattern is the GNU regular expression compiler: it
+   compiles PATTERN (of length LENGTH) and puts the result in BUFP.
+   Returns 0 if the pattern was valid, otherwise an error string.
+
+   Assumes the 'allocated' (and perhaps 'buffer') and 'translate' fields
+   are set in BUFP on entry.  */
+
+const char *
+re_compile_pattern(const char *pattern, size_t length,
+                   struct re_pattern_buffer *bufp) {
+    reg_errcode_t ret;
+
+    /* And GNU code determines whether or not to get register information
+       by passing null for the REGS argument to re_match, etc., not by
+       setting no_sub, unless RE_NO_SUB is set.  */
+    bufp->no_sub = !!(re_syntax_options & RE_NO_SUB);
+
+    /* Match anchors at newline.  */
+    bufp->newline_anchor = 1;
+
+    ret = re_compile_internal(bufp, pattern, length, re_syntax_options);
+
+    if (!ret)
+        return NULL;
+    return gettext(__re_error_msgid + __re_error_msgid_idx[(int) ret]);
+}
+
+
+/* Set by 're_set_syntax' to the current regexp syntax to recognize.  Can
+   also be assigned to arbitrarily: each pattern buffer stores its own
+   syntax, so it can be changed between regex compilations.  */
+/* This has no initializer because initialized variables in Emacs
+   become read-only after dumping.  */
+reg_syntax_t re_syntax_options;
+
+
+/* Specify the precise syntax of regexps for compilation.  This provides
+   for compatibility for various utilities which historically have
+   different, incompatible syntaxes.
+
+   The argument SYNTAX is a bit mask comprised of the various bits
+   defined in regex.h.  We return the old syntax.  */
+
+reg_syntax_t
+re_set_syntax(reg_syntax_t syntax) {
+    reg_syntax_t ret = re_syntax_options;
+
+    re_syntax_options = syntax;
+    return ret;
+}
+
+int
+re_compile_fastmap(struct re_pattern_buffer *bufp) {
+    re_dfa_t *dfa = bufp->buffer;
+    char *fastmap = bufp->fastmap;
+
+    memset(fastmap, '\0', sizeof(char) * SBC_MAX);
+    re_compile_fastmap_iter(bufp, dfa->init_state, fastmap);
+    if (dfa->init_state != dfa->init_state_word)
+        re_compile_fastmap_iter(bufp, dfa->init_state_word, fastmap);
+    if (dfa->init_state != dfa->init_state_nl)
+        re_compile_fastmap_iter(bufp, dfa->init_state_nl, fastmap);
+    if (dfa->init_state != dfa->init_state_begbuf)
+        re_compile_fastmap_iter(bufp, dfa->init_state_begbuf, fastmap);
+    bufp->fastmap_accurate = 1;
+    return 0;
+}
+
+
+static inline void
+__attribute__ ((always_inline))
+re_set_fastmap(char *fastmap, bool icase, int ch) {
+    fastmap[ch] = 1;
+    if (icase)
+        fastmap[tolower(ch)] = 1;
+}
+
+/* Helper function for re_compile_fastmap.
+   Compile fastmap for the initial_state INIT_STATE.  */
+
+static void
+re_compile_fastmap_iter(regex_t *bufp, const re_dfastate_t *init_state,
+                        char *fastmap) {
+    re_dfa_t *dfa = bufp->buffer;
+    Idx node_cnt;
+    bool icase = (dfa->mb_cur_max == 1 && (bufp->syntax & RE_ICASE));
+    for (node_cnt = 0; node_cnt < init_state->nodes.nelem; ++node_cnt) {
+        Idx node = init_state->nodes.elems[node_cnt];
+        re_token_type_t type = dfa->nodes[node].type;
+
+        if (type == CHARACTER) {
+            re_set_fastmap(fastmap, icase, dfa->nodes[node].opr.c);
+        } else if (type == SIMPLE_BRACKET) {
+            int i, ch;
+            for (i = 0, ch = 0; i < BITSET_WORDS; ++i) {
+                int j;
+                bitset_word_t w = dfa->nodes[node].opr.sbcset[i];
+                for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+                    if (w & ((bitset_word_t) 1 << j))
+                        re_set_fastmap(fastmap, icase, ch);
+            }
+        } else if (type == OP_PERIOD
+                   || type == END_OF_RE) {
+            memset(fastmap, '\1', sizeof(char) * SBC_MAX);
+            if (type == END_OF_RE)
+                bufp->can_be_null = 1;
+            return;
+        }
+    }
+}
+
+/* Entry point for POSIX code.  */
+/* regcomp takes a regular expression as a string and compiles it.
+
+   PREG is a regex_t *.  We do not expect any fields to be initialized,
+   since POSIX says we shouldn't.  Thus, we set
+
+     'buffer' to the compiled pattern;
+     'used' to the length of the compiled pattern;
+     'syntax' to RE_SYNTAX_POSIX_EXTENDED if the
+       REG_EXTENDED bit in CFLAGS is set; otherwise, to
+       RE_SYNTAX_POSIX_BASIC;
+     'newline_anchor' to REG_NEWLINE being set in CFLAGS;
+     'fastmap' to an allocated space for the fastmap;
+     'fastmap_accurate' to zero;
+     're_nsub' to the number of subexpressions in PATTERN.
+
+   PATTERN is the address of the pattern string.
+
+   CFLAGS is a series of bits which affect compilation.
+
+     If REG_EXTENDED is set, we use POSIX extended syntax; otherwise, we
+     use POSIX basic syntax.
+
+     If REG_NEWLINE is set, then . and [^...] don't match newline.
+     Also, regexec will try a match beginning after every newline.
+
+     If REG_ICASE is set, then we considers upper- and lowercase
+     versions of letters to be equivalent when matching.
+
+     If REG_NOSUB is set, then when PREG is passed to regexec, that
+     routine will report only success or failure, and nothing about the
+     registers.
+
+   It returns 0 if it succeeds, nonzero if it doesn't.  (See regex.h for
+   the return codes and their meanings.)  */
+
+int
+regcomp(regex_t *_Restrict_ preg, const char *_Restrict_ pattern, int cflags) {
+    reg_errcode_t ret;
+    reg_syntax_t syntax = ((cflags & REG_EXTENDED) ? RE_SYNTAX_POSIX_EXTENDED
+                                                   : RE_SYNTAX_POSIX_BASIC);
+
+    preg->buffer = NULL;
+    preg->allocated = 0;
+    preg->used = 0;
+
+    /* Try to allocate space for the fastmap.  */
+    preg->fastmap = re_malloc(
+    char, SBC_MAX);
+    if ((preg->fastmap == NULL))
+        return REG_ESPACE;
+
+    syntax |= (cflags & REG_ICASE) ? RE_ICASE : 0;
+
+    /* If REG_NEWLINE is set, newlines are treated differently.  */
+    if (cflags & REG_NEWLINE) { /* REG_NEWLINE implies neither . nor [^...] match newline.  */
+        syntax &= ~RE_DOT_NEWLINE;
+        syntax |= RE_HAT_LISTS_NOT_NEWLINE;
+        /* It also changes the matching behavior.  */
+        preg->newline_anchor = 1;
+    } else
+        preg->newline_anchor = 0;
+    preg->no_sub = !!(cflags & REG_NOSUB);
+    preg->translate = NULL;
+
+    ret = re_compile_internal(preg, pattern, strlen(pattern), syntax);
+
+    /* POSIX doesn't distinguish between an unmatched open-group and an
+       unmatched close-group: both are REG_EPAREN.  */
+    if (ret == REG_ERPAREN)
+        ret = REG_EPAREN;
+
+    /* We have already checked preg->fastmap != NULL.  */
+    if ((ret == REG_NOERROR))
+        /* Compute the fastmap now, since regexec cannot modify the pattern
+           buffer.  This function never fails in this implementation.  */
+        (void) re_compile_fastmap(preg);
+    else {
+        /* Some error occurred while compiling the expression.  */
+        re_free(preg->fastmap);
+        preg->fastmap = NULL;
+    }
+
+    return (int) ret;
+}
+
+/* Returns a message corresponding to an error code, ERRCODE, returned
+   from either regcomp or regexec.   We don't use PREG here.  */
+
+size_t
+regerror(int errcode, const regex_t *_Restrict_ preg, char *_Restrict_ errbuf,
+         size_t errbuf_size) {
+    const char *msg;
+    size_t msg_size;
+    int nerrcodes = sizeof __re_error_msgid_idx / sizeof __re_error_msgid_idx[0];
+
+    if ((errcode < 0 || errcode >= nerrcodes))
+        /* Only error codes returned by the rest of the code should be passed
+           to this routine.  If we are given anything else, or if other regex
+           code generates an invalid error code, then the program has a bug.
+           Dump core so we can fix it.  */
+        abort();
+
+    msg = gettext(__re_error_msgid + __re_error_msgid_idx[errcode]);
+
+    msg_size = strlen(msg) + 1; /* Includes the null.  */
+
+    if ((errbuf_size != 0)) {
+        size_t cpy_size = msg_size;
+        if ((msg_size > errbuf_size)) {
+            cpy_size = errbuf_size - 1;
+            errbuf[cpy_size] = '\0';
+        }
+        memcpy(errbuf, msg, cpy_size);
+    }
+
+    return msg_size;
+}
+
+static void
+free_dfa_content(re_dfa_t *dfa) {
+    Idx i, j;
+
+    if (dfa->nodes)
+        for (i = 0; i < dfa->nodes_len; ++i)
+            free_token(dfa->nodes + i);
+    re_free(dfa->nexts);
+    for (i = 0; i < dfa->nodes_len; ++i) {
+        if (dfa->eclosures != NULL)
+            re_node_set_free(dfa->eclosures + i);
+        if (dfa->inveclosures != NULL)
+            re_node_set_free(dfa->inveclosures + i);
+        if (dfa->edests != NULL)
+            re_node_set_free(dfa->edests + i);
+    }
+    re_free(dfa->edests);
+    re_free(dfa->eclosures);
+    re_free(dfa->inveclosures);
+    re_free(dfa->nodes);
+
+    if (dfa->state_table)
+        for (i = 0; i <= dfa->state_hash_mask; ++i) {
+            struct re_state_table_entry *entry = dfa->state_table + i;
+            for (j = 0; j < entry->num; ++j) {
+                re_dfastate_t *state = entry->array[j];
+                free_state(state);
+            }
+            re_free(entry->array);
+        }
+    re_free(dfa->state_table);
+    re_free(dfa->subexp_map);
+    re_free(dfa);
+}
+
+
+/* Free dynamically allocated space used by PREG.  */
+
+void
+regfree(regex_t *preg) {
+    re_dfa_t *dfa = preg->buffer;
+    if ((dfa != NULL)) {
+        lock_fini(dfa->lock);
+        free_dfa_content(dfa);
+    }
+    preg->buffer = NULL;
+    preg->allocated = 0;
+
+    re_free(preg->fastmap);
+    preg->fastmap = NULL;
+
+    re_free(preg->translate);
+    preg->translate = NULL;
+}
+
+/* Internal entry point.
+   Compile the regular expression PATTERN, whose length is LENGTH.
+   SYNTAX indicate regular expression's syntax.  */
+
+static reg_errcode_t
+re_compile_internal(regex_t *preg, const char *pattern, size_t length,
+                    reg_syntax_t syntax) {
+    reg_errcode_t err = REG_NOERROR;
+    re_dfa_t *dfa;
+    re_string_t regexp;
+
+    /* Initialize the pattern buffer.  */
+    preg->fastmap_accurate = 0;
+    preg->syntax = syntax;
+    preg->not_bol = preg->not_eol = 0;
+    preg->used = 0;
+    preg->re_nsub = 0;
+    preg->can_be_null = 0;
+    preg->regs_allocated = REGS_UNALLOCATED;
+
+    /* Initialize the dfa.  */
+    dfa = preg->buffer;
+    if ((preg->allocated < sizeof(re_dfa_t))) {
+        /* If zero allocated, but buffer is non-null, try to realloc
+       enough space.  This loses if buffer's address is bogus, but
+       that is the user's responsibility.  If ->buffer is NULL this
+       is a simple allocation.  */
+        dfa = re_realloc(preg->buffer, re_dfa_t, 1);
+        if (dfa == NULL)
+            return REG_ESPACE;
+        preg->allocated = sizeof(re_dfa_t);
+        preg->buffer = dfa;
+    }
+    preg->used = sizeof(re_dfa_t);
+
+    err = init_dfa(dfa, length);
+    if ((err == REG_NOERROR && lock_init(dfa->lock) != 0))
+        err = REG_ESPACE;
+    if ((err != REG_NOERROR)) {
+        free_dfa_content(dfa);
+        preg->buffer = NULL;
+        preg->allocated = 0;
+        return err;
+    }
+    err = re_string_construct(&regexp, pattern, length, preg->translate,
+                              (syntax & RE_ICASE) != 0, dfa);
+    if ((err != REG_NOERROR)) {
+        re_compile_internal_free_return:
+        free_workarea_compile(preg);
+        re_string_destruct(&regexp);
+        lock_fini(dfa->lock);
+        free_dfa_content(dfa);
+        preg->buffer = NULL;
+        preg->allocated = 0;
+        return err;
+    }
+
+    /* Parse the regular expression, and build a structure tree.  */
+    preg->re_nsub = 0;
+    dfa->str_tree = parse(&regexp, preg, syntax, &err);
+    if ((dfa->str_tree == NULL))
+        goto re_compile_internal_free_return;
+
+    /* Analyze the tree and create the nfa.  */
+    err = analyze(preg);
+    if ((err != REG_NOERROR))
+        goto re_compile_internal_free_return;
+
+    /* Then create the initial state of the dfa.  */
+    err = create_initial_state(dfa);
+
+    /* Release work areas.  */
+    free_workarea_compile(preg);
+    re_string_destruct(&regexp);
+
+    if ((err != REG_NOERROR)) {
+        lock_fini(dfa->lock);
+        free_dfa_content(dfa);
+        preg->buffer = NULL;
+        preg->allocated = 0;
+    }
+
+    return err;
+}
+
+/* Initialize DFA.  We use the length of the regular expression PAT_LEN
+   as the initial length of some arrays.  */
+
+static reg_errcode_t
+init_dfa(re_dfa_t *dfa, size_t pat_len) {
+    __re_size_t table_size;
+    const char *codeset_name;
+
+    size_t max_i18n_object_size = 0;
+
+    size_t max_object_size =
+            MAX (sizeof(struct re_state_table_entry),
+                 MAX(sizeof(re_token_t),
+                     MAX(sizeof(re_node_set),
+                         MAX(sizeof(regmatch_t),
+                             max_i18n_object_size))));
+
+    memset(dfa, '\0', sizeof(re_dfa_t));
+
+    /* Force allocation of str_tree_storage the first time.  */
+    dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+
+    /* Avoid overflows.  The extra "/ 2" is for the table_size doubling
+       calculation below, and for similar doubling calculations
+       elsewhere.  And it's <= rather than <, because some of the
+       doubling calculations add 1 afterwards.  */
+    if ((MIN (IDX_MAX, SIZE_MAX / max_object_size) / 2
+         <= pat_len))
+        return REG_ESPACE;
+
+    dfa->nodes_alloc = pat_len + 1;
+    dfa->nodes = re_malloc(re_token_t, dfa->nodes_alloc);
+
+    /*  table_size = 2 ^ ceil(log pat_len) */
+    for (table_size = 1;; table_size <<= 1)
+        if (table_size > pat_len)
+            break;
+
+    dfa->state_table = calloc(sizeof(struct re_state_table_entry), table_size);
+    dfa->state_hash_mask = table_size - 1;
+
+    dfa->mb_cur_max = MB_CUR_MAX;
+    codeset_name = nl_langinfo(CODESET);
+    if ((codeset_name[0] == 'U' || codeset_name[0] == 'u')
+        && (codeset_name[1] == 'T' || codeset_name[1] == 't')
+        && (codeset_name[2] == 'F' || codeset_name[2] == 'f')
+        && strcmp(codeset_name + 3 + (codeset_name[3] == '-'), "8") == 0)
+        dfa->is_utf8 = 1;
+
+    /* We check exhaustively in the loop below if this charset is a
+       superset of ASCII.  */
+    dfa->map_notascii = 0;
+
+    if ((dfa->nodes == NULL || dfa->state_table == NULL))
+        return REG_ESPACE;
+    return REG_NOERROR;
+}
+
+/* Initialize WORD_CHAR table, which indicate which character is
+   "word".  In this case "word" means that it is the word construction
+   character used by some operators like "\<", "\>", etc.  */
+
+static void
+init_word_char(re_dfa_t *dfa) {
+    int i = 0;
+    int j;
+    int ch = 0;
+    dfa->word_ops_used = 1;
+    if ((dfa->map_notascii == 0)) {
+        /* Avoid uint32_t and uint64_t as some non-GCC platforms lack
+       them, an issue when this code is used in Gnulib.  */
+        bitset_word_t bits0 = 0x00000000;
+        bitset_word_t bits1 = 0x03ff0000;
+        bitset_word_t bits2 = 0x87fffffe;
+        bitset_word_t bits3 = 0x07fffffe;
+        if (BITSET_WORD_BITS == 64) {
+            /* Pacify gcc -Woverflow on 32-bit platformns.  */
+            dfa->word_char[0] = bits1 << 31 << 1 | bits0;
+            dfa->word_char[1] = bits3 << 31 << 1 | bits2;
+            i = 2;
+        } else if (BITSET_WORD_BITS == 32) {
+            dfa->word_char[0] = bits0;
+            dfa->word_char[1] = bits1;
+            dfa->word_char[2] = bits2;
+            dfa->word_char[3] = bits3;
+            i = 4;
+        } else
+            goto general_case;
+        ch = 128;
+
+        if ((dfa->is_utf8)) {
+            memset(&dfa->word_char[i], '\0', (SBC_MAX - ch) / 8);
+            return;
+        }
+    }
+
+    general_case:
+    for (; i < BITSET_WORDS; ++i)
+        for (j = 0; j < BITSET_WORD_BITS; ++j, ++ch)
+            if (isalnum(ch) || ch == '_')
+                dfa->word_char[i] |= (bitset_word_t) 1 << j;
+}
+
+/* Free the work area which are only used while compiling.  */
+
+static void
+free_workarea_compile(regex_t *preg) {
+    re_dfa_t *dfa = preg->buffer;
+    bin_tree_storage_t *storage, *next;
+    for (storage = dfa->str_tree_storage; storage; storage = next) {
+        next = storage->next;
+        re_free(storage);
+    }
+    dfa->str_tree_storage = NULL;
+    dfa->str_tree_storage_idx = BIN_TREE_STORAGE_SIZE;
+    dfa->str_tree = NULL;
+    re_free(dfa->org_indices);
+    dfa->org_indices = NULL;
+}
+
+/* Create initial states for all contexts.  */
+
+static reg_errcode_t
+create_initial_state(re_dfa_t *dfa) {
+    Idx first, i;
+    reg_errcode_t err;
+    re_node_set init_nodes;
+
+    /* Initial states have the epsilon closure of the node which is
+       the first node of the regular expression.  */
+    first = dfa->str_tree->first->node_idx;
+    dfa->init_node = first;
+    err = re_node_set_init_copy(&init_nodes, dfa->eclosures + first);
+    if ((err != REG_NOERROR))
+        return err;
+
+    /* The back-references which are in initial states can epsilon transit,
+       since in this case all of the subexpressions can be null.
+       Then we add epsilon closures of the nodes which are the next nodes of
+       the back-references.  */
+    if (dfa->nbackref > 0)
+        for (i = 0; i < init_nodes.nelem; ++i) {
+            Idx node_idx = init_nodes.elems[i];
+            re_token_type_t type = dfa->nodes[node_idx].type;
+
+            Idx clexp_idx;
+            if (type != OP_BACK_REF)
+                continue;
+            for (clexp_idx = 0; clexp_idx < init_nodes.nelem; ++clexp_idx) {
+                re_token_t *clexp_node;
+                clexp_node = dfa->nodes + init_nodes.elems[clexp_idx];
+                if (clexp_node->type == OP_CLOSE_SUBEXP
+                    && clexp_node->opr.idx == dfa->nodes[node_idx].opr.idx)
+                    break;
+            }
+            if (clexp_idx == init_nodes.nelem)
+                continue;
+
+            if (type == OP_BACK_REF) {
+                Idx dest_idx = dfa->edests[node_idx].elems[0];
+                if (!re_node_set_contains(&init_nodes, dest_idx)) {
+                    reg_errcode_t merge_err
+                            = re_node_set_merge(&init_nodes, dfa->eclosures + dest_idx);
+                    if (merge_err != REG_NOERROR)
+                        return merge_err;
+                    i = 0;
+                }
+            }
+        }
+
+    /* It must be the first time to invoke acquire_state.  */
+    dfa->init_state = re_acquire_state_context(&err, dfa, &init_nodes, 0);
+    /* We don't check ERR here, since the initial state must not be NULL.  */
+    if ((dfa->init_state == NULL))
+        return err;
+    if (dfa->init_state->has_constraint) {
+        dfa->init_state_word = re_acquire_state_context(&err, dfa, &init_nodes,
+                                                        CONTEXT_WORD);
+        dfa->init_state_nl = re_acquire_state_context(&err, dfa, &init_nodes,
+                                                      CONTEXT_NEWLINE);
+        dfa->init_state_begbuf = re_acquire_state_context(&err, dfa,
+                                                          &init_nodes,
+                                                          CONTEXT_NEWLINE
+                                                          | CONTEXT_BEGBUF);
+        if ((dfa->init_state_word == NULL
+             || dfa->init_state_nl == NULL
+             || dfa->init_state_begbuf == NULL))
+            return err;
+    } else
+        dfa->init_state_word = dfa->init_state_nl
+                = dfa->init_state_begbuf = dfa->init_state;
+
+    re_node_set_free(&init_nodes);
+    return REG_NOERROR;
+}
+
+
+/* Analyze the structure tree, and calculate "first", "next", "edest",
+   "eclosure", and "inveclosure".  */
+
+static reg_errcode_t
+analyze(regex_t *preg) {
+    re_dfa_t *dfa = preg->buffer;
+    reg_errcode_t ret;
+
+    /* Allocate arrays.  */
+    dfa->nexts = re_malloc(Idx, dfa->nodes_alloc);
+    dfa->org_indices = re_malloc(Idx, dfa->nodes_alloc);
+    dfa->edests = re_malloc(re_node_set, dfa->nodes_alloc);
+    dfa->eclosures = re_malloc(re_node_set, dfa->nodes_alloc);
+    if ((dfa->nexts == NULL || dfa->org_indices == NULL
+         || dfa->edests == NULL || dfa->eclosures == NULL))
+        return REG_ESPACE;
+
+    dfa->subexp_map = re_malloc(Idx, preg->re_nsub);
+    if (dfa->subexp_map != NULL) {
+        Idx i;
+        for (i = 0; i < preg->re_nsub; i++)
+            dfa->subexp_map[i] = i;
+        preorder(dfa->str_tree, optimize_subexps, dfa);
+        for (i = 0; i < preg->re_nsub; i++)
+            if (dfa->subexp_map[i] != i)
+                break;
+        if (i == preg->re_nsub) {
+            re_free(dfa->subexp_map);
+            dfa->subexp_map = NULL;
+        }
+    }
+
+    ret = postorder(dfa->str_tree, lower_subexps, preg);
+    if ((ret != REG_NOERROR))
+        return ret;
+    ret = postorder(dfa->str_tree, calc_first, dfa);
+    if ((ret != REG_NOERROR))
+        return ret;
+    preorder(dfa->str_tree, calc_next, dfa);
+    ret = preorder(dfa->str_tree, link_nfa_nodes, dfa);
+    if ((ret != REG_NOERROR))
+        return ret;
+    ret = calc_eclosure(dfa);
+    if ((ret != REG_NOERROR))
+        return ret;
+
+    /* We only need this during the prune_impossible_nodes pass in regexec.c;
+       skip it if p_i_n will not run, as calc_inveclosure can be quadratic.  */
+    if ((!preg->no_sub && preg->re_nsub > 0 && dfa->has_plural_match)
+        || dfa->nbackref) {
+        dfa->inveclosures = re_malloc(re_node_set, dfa->nodes_len);
+        if ((dfa->inveclosures == NULL))
+            return REG_ESPACE;
+        ret = calc_inveclosure(dfa);
+    }
+
+    return ret;
+}
+
+/* Our parse trees are very unbalanced, so we cannot use a stack to
+   implement parse tree visits.  Instead, we use parent pointers and
+   some hairy code in these two functions.  */
+static reg_errcode_t
+postorder(bin_tree_t *root, reg_errcode_t (fn(void *, bin_tree_t *)),
+          void *extra) {
+    bin_tree_t *node, *prev;
+
+    for (node = root;;) {
+        /* Descend down the tree, preferably to the left (or to the right
+       if that's the only child).  */
+        while (node->left || node->right)
+            if (node->left)
+                node = node->left;
+            else
+                node = node->right;
+
+        do {
+            reg_errcode_t err = fn(extra, node);
+            if ((err != REG_NOERROR))
+                return err;
+            if (node->parent == NULL)
+                return REG_NOERROR;
+            prev = node;
+            node = node->parent;
+        }
+            /* Go up while we have a node that is reached from the right.  */
+        while (node->right == prev || node->right == NULL);
+        node = node->right;
+    }
+}
+
+static reg_errcode_t
+preorder(bin_tree_t *root, reg_errcode_t (fn(void *, bin_tree_t *)),
+         void *extra) {
+    bin_tree_t *node;
+
+    for (node = root;;) {
+        reg_errcode_t err = fn(extra, node);
+        if ((err != REG_NOERROR))
+            return err;
+
+        /* Go to the left node, or up and to the right.  */
+        if (node->left)
+            node = node->left;
+        else {
+            bin_tree_t *prev = NULL;
+            while (node->right == prev || node->right == NULL) {
+                prev = node;
+                node = node->parent;
+                if (!node)
+                    return REG_NOERROR;
+            }
+            node = node->right;
+        }
+    }
+}
+
+/* Optimization pass: if a SUBEXP is entirely contained, strip it and tell
+   re_search_internal to map the inner one's opr.idx to this one's.  Adjust
+   backreferences as well.  Requires a preorder visit.  */
+static reg_errcode_t
+optimize_subexps(void *extra, bin_tree_t *node) {
+    re_dfa_t *dfa = (re_dfa_t *) extra;
+
+    if (node->token.type == OP_BACK_REF && dfa->subexp_map) {
+        int idx = node->token.opr.idx;
+        node->token.opr.idx = dfa->subexp_map[idx];
+        dfa->used_bkref_map |= 1 << node->token.opr.idx;
+    } else if (node->token.type == SUBEXP
+               && node->left && node->left->token.type == SUBEXP) {
+        Idx other_idx = node->left->token.opr.idx;
+
+        node->left = node->left->left;
+        if (node->left)
+            node->left->parent = node;
+
+        dfa->subexp_map[other_idx] = dfa->subexp_map[node->token.opr.idx];
+        if (other_idx < BITSET_WORD_BITS)
+            dfa->used_bkref_map &= ~((bitset_word_t) 1 << other_idx);
+    }
+
+    return REG_NOERROR;
+}
+
+/* Lowering pass: Turn each SUBEXP node into the appropriate concatenation
+   of OP_OPEN_SUBEXP, the body of the SUBEXP (if any) and OP_CLOSE_SUBEXP.  */
+static reg_errcode_t
+lower_subexps(void *extra, bin_tree_t *node) {
+    regex_t *preg = (regex_t *) extra;
+    reg_errcode_t err = REG_NOERROR;
+
+    if (node->left && node->left->token.type == SUBEXP) {
+        node->left = lower_subexp(&err, preg, node->left);
+        if (node->left)
+            node->left->parent = node;
+    }
+    if (node->right && node->right->token.type == SUBEXP) {
+        node->right = lower_subexp(&err, preg, node->right);
+        if (node->right)
+            node->right->parent = node;
+    }
+
+    return err;
+}
+
+static bin_tree_t *
+lower_subexp(reg_errcode_t *err, regex_t *preg, bin_tree_t *node) {
+    re_dfa_t *dfa = preg->buffer;
+    bin_tree_t *body = node->left;
+    bin_tree_t *op, *cls, *tree1, *tree;
+
+    if (preg->no_sub
+        /* We do not optimize empty subexpressions, because otherwise we may
+       have bad CONCAT nodes with NULL children.  This is obviously not
+       very common, so we do not lose much.  An example that triggers
+       this case is the sed "script" /\(\)/x.  */
+        && node->left != NULL
+        && (node->token.opr.idx >= BITSET_WORD_BITS
+            || !(dfa->used_bkref_map
+                 & ((bitset_word_t) 1 << node->token.opr.idx))))
+        return node->left;
+
+    /* Convert the SUBEXP node to the concatenation of an
+       OP_OPEN_SUBEXP, the contents, and an OP_CLOSE_SUBEXP.  */
+    op = create_tree(dfa, NULL, NULL, OP_OPEN_SUBEXP);
+    cls = create_tree(dfa, NULL, NULL, OP_CLOSE_SUBEXP);
+    tree1 = body ? create_tree(dfa, body, cls, CONCAT) : cls;
+    tree = create_tree(dfa, op, tree1, CONCAT);
+    if ((tree == NULL || tree1 == NULL
+         || op == NULL || cls == NULL)) {
+        *err = REG_ESPACE;
+        return NULL;
+    }
+
+    op->token.opr.idx = cls->token.opr.idx = node->token.opr.idx;
+    op->token.opt_subexp = cls->token.opt_subexp = node->token.opt_subexp;
+    return tree;
+}
+
+/* Pass 1 in building the NFA: compute FIRST and create unlinked automaton
+   nodes.  Requires a postorder visit.  */
+static reg_errcode_t
+calc_first(void *extra, bin_tree_t *node) {
+    re_dfa_t *dfa = (re_dfa_t *) extra;
+    if (node->token.type == CONCAT) {
+        node->first = node->left->first;
+        node->node_idx = node->left->node_idx;
+    } else {
+        node->first = node;
+        node->node_idx = re_dfa_add_node(dfa, node->token);
+        if ((node->node_idx == -1))
+            return REG_ESPACE;
+        if (node->token.type == ANCHOR)
+            dfa->nodes[node->node_idx].constraint = node->token.opr.ctx_type;
+    }
+    return REG_NOERROR;
+}
+
+/* Pass 2: compute NEXT on the tree.  Preorder visit.  */
+static reg_errcode_t
+calc_next(void *extra, bin_tree_t *node) {
+    switch (node->token.type) {
+        case OP_DUP_ASTERISK:
+            node->left->next = node;
+            break;
+        case CONCAT:
+            node->left->next = node->right->first;
+            node->right->next = node->next;
+            break;
+        default:
+            if (node->left)
+                node->left->next = node->next;
+            if (node->right)
+                node->right->next = node->next;
+            break;
+    }
+    return REG_NOERROR;
+}
+
+/* Pass 3: link all DFA nodes to their NEXT node (any order will do).  */
+static reg_errcode_t
+link_nfa_nodes(void *extra, bin_tree_t *node) {
+    re_dfa_t *dfa = (re_dfa_t *) extra;
+    Idx idx = node->node_idx;
+    reg_errcode_t err = REG_NOERROR;
+
+    switch (node->token.type) {
+        case CONCAT:
+            break;
+
+        case END_OF_RE:
+            assert(node->next == NULL);
+            break;
+
+        case OP_DUP_ASTERISK:
+        case OP_ALT: {
+            Idx left, right;
+            dfa->has_plural_match = 1;
+            if (node->left != NULL)
+                left = node->left->first->node_idx;
+            else
+                left = node->next->node_idx;
+            if (node->right != NULL)
+                right = node->right->first->node_idx;
+            else
+                right = node->next->node_idx;
+            assert(left > -1);
+            assert(right > -1);
+            err = re_node_set_init_2(dfa->edests + idx, left, right);
+        }
+            break;
+
+        case ANCHOR:
+        case OP_OPEN_SUBEXP:
+        case OP_CLOSE_SUBEXP:
+            err = re_node_set_init_1(dfa->edests + idx, node->next->node_idx);
+            break;
+
+        case OP_BACK_REF:
+            dfa->nexts[idx] = node->next->node_idx;
+            if (node->token.type == OP_BACK_REF)
+                err = re_node_set_init_1(dfa->edests + idx, dfa->nexts[idx]);
+            break;
+
+        default:
+            assert(!IS_EPSILON_NODE(node->token.type));
+            dfa->nexts[idx] = node->next->node_idx;
+            break;
+    }
+
+    return err;
+}
+
+/* Duplicate the epsilon closure of the node ROOT_NODE.
+   Note that duplicated nodes have constraint INIT_CONSTRAINT in addition
+   to their own constraint.  */
+
+static reg_errcode_t
+duplicate_node_closure(re_dfa_t *dfa, Idx top_org_node, Idx top_clone_node,
+                       Idx root_node, unsigned int init_constraint) {
+    Idx org_node, clone_node;
+    bool ok;
+    unsigned int constraint = init_constraint;
+    for (org_node = top_org_node, clone_node = top_clone_node;;) {
+        Idx org_dest, clone_dest;
+        if (dfa->nodes[org_node].type == OP_BACK_REF) {
+            /* If the back reference epsilon-transit, its destination must
+               also have the constraint.  Then duplicate the epsilon closure
+               of the destination of the back reference, and store it in
+               edests of the back reference.  */
+            org_dest = dfa->nexts[org_node];
+            re_node_set_empty(dfa->edests + clone_node);
+            clone_dest = duplicate_node(dfa, org_dest, constraint);
+            if ((clone_dest == -1))
+                return REG_ESPACE;
+            dfa->nexts[clone_node] = dfa->nexts[org_node];
+            ok = re_node_set_insert(dfa->edests + clone_node, clone_dest);
+            if ((!ok))
+                return REG_ESPACE;
+        } else if (dfa->edests[org_node].nelem == 0) {
+            /* In case of the node can't epsilon-transit, don't duplicate the
+               destination and store the original destination as the
+               destination of the node.  */
+            dfa->nexts[clone_node] = dfa->nexts[org_node];
+            break;
+        } else if (dfa->edests[org_node].nelem == 1) {
+            /* In case of the node can epsilon-transit, and it has only one
+               destination.  */
+            org_dest = dfa->edests[org_node].elems[0];
+            re_node_set_empty(dfa->edests + clone_node);
+            /* If the node is root_node itself, it means the epsilon closure
+               has a loop.  Then tie it to the destination of the root_node.  */
+            if (org_node == root_node && clone_node != org_node) {
+                ok = re_node_set_insert(dfa->edests + clone_node, org_dest);
+                if ((!ok))
+                    return REG_ESPACE;
+                break;
+            }
+            /* In case the node has another constraint, append it.  */
+            constraint |= dfa->nodes[org_node].constraint;
+            clone_dest = duplicate_node(dfa, org_dest, constraint);
+            if ((clone_dest == -1))
+                return REG_ESPACE;
+            ok = re_node_set_insert(dfa->edests + clone_node, clone_dest);
+            if ((!ok))
+                return REG_ESPACE;
+        } else /* dfa->edests[org_node].nelem == 2 */
+        {
+            /* In case of the node can epsilon-transit, and it has two
+               destinations. In the bin_tree_t and DFA, that's '|' and '*'.   */
+            org_dest = dfa->edests[org_node].elems[0];
+            re_node_set_empty(dfa->edests + clone_node);
+            /* Search for a duplicated node which satisfies the constraint.  */
+            clone_dest = search_duplicated_node(dfa, org_dest, constraint);
+            if (clone_dest == -1) {
+                /* There is no such duplicated node, create a new one.  */
+                reg_errcode_t err;
+                clone_dest = duplicate_node(dfa, org_dest, constraint);
+                if ((clone_dest == -1))
+                    return REG_ESPACE;
+                ok = re_node_set_insert(dfa->edests + clone_node, clone_dest);
+                if ((!ok))
+                    return REG_ESPACE;
+                err = duplicate_node_closure(dfa, org_dest, clone_dest,
+                                             root_node, constraint);
+                if ((err != REG_NOERROR))
+                    return err;
+            } else {
+                /* There is a duplicated node which satisfies the constraint,
+               use it to avoid infinite loop.  */
+                ok = re_node_set_insert(dfa->edests + clone_node, clone_dest);
+                if ((!ok))
+                    return REG_ESPACE;
+            }
+
+            org_dest = dfa->edests[org_node].elems[1];
+            clone_dest = duplicate_node(dfa, org_dest, constraint);
+            if ((clone_dest == -1))
+                return REG_ESPACE;
+            ok = re_node_set_insert(dfa->edests + clone_node, clone_dest);
+            if ((!ok))
+                return REG_ESPACE;
+        }
+        org_node = org_dest;
+        clone_node = clone_dest;
+    }
+    return REG_NOERROR;
+}
+
+/* Search for a node which is duplicated from the node ORG_NODE, and
+   satisfies the constraint CONSTRAINT.  */
+
+static Idx
+search_duplicated_node(const re_dfa_t *dfa, Idx org_node,
+                       unsigned int constraint) {
+    Idx idx;
+    for (idx = dfa->nodes_len - 1; dfa->nodes[idx].duplicated && idx > 0; --idx) {
+        if (org_node == dfa->org_indices[idx]
+            && constraint == dfa->nodes[idx].constraint)
+            return idx; /* Found.  */
+    }
+    return -1; /* Not found.  */
+}
+
+/* Duplicate the node whose index is ORG_IDX and set the constraint CONSTRAINT.
+   Return the index of the new node, or -1 if insufficient storage is
+   available.  */
+
+static Idx
+duplicate_node(re_dfa_t *dfa, Idx org_idx, unsigned int constraint) {
+    Idx dup_idx = re_dfa_add_node(dfa, dfa->nodes[org_idx]);
+    if ((dup_idx != -1)) {
+        dfa->nodes[dup_idx].constraint = constraint;
+        dfa->nodes[dup_idx].constraint |= dfa->nodes[org_idx].constraint;
+        dfa->nodes[dup_idx].duplicated = 1;
+
+        /* Store the index of the original node.  */
+        dfa->org_indices[dup_idx] = org_idx;
+    }
+    return dup_idx;
+}
+
+static reg_errcode_t
+calc_inveclosure(re_dfa_t *dfa) {
+    Idx src, idx;
+    bool ok;
+    for (idx = 0; idx < dfa->nodes_len; ++idx)
+        re_node_set_init_empty(dfa->inveclosures + idx);
+
+    for (src = 0; src < dfa->nodes_len; ++src) {
+        Idx *elems = dfa->eclosures[src].elems;
+        for (idx = 0; idx < dfa->eclosures[src].nelem; ++idx) {
+            ok = re_node_set_insert_last(dfa->inveclosures + elems[idx], src);
+            if ((!ok))
+                return REG_ESPACE;
+        }
+    }
+
+    return REG_NOERROR;
+}
+
+/* Calculate "eclosure" for all the node in DFA.  */
+
+static reg_errcode_t
+calc_eclosure(re_dfa_t *dfa) {
+    Idx node_idx;
+    bool incomplete;
+    incomplete = false;
+    /* For each nodes, calculate epsilon closure.  */
+    for (node_idx = 0;; ++node_idx) {
+        reg_errcode_t err;
+        re_node_set eclosure_elem;
+        if (node_idx == dfa->nodes_len) {
+            if (!incomplete)
+                break;
+            incomplete = false;
+            node_idx = 0;
+        }
+
+        /* If we have already calculated, skip it.  */
+        if (dfa->eclosures[node_idx].nelem != 0)
+            continue;
+        /* Calculate epsilon closure of 'node_idx'.  */
+        err = calc_eclosure_iter(&eclosure_elem, dfa, node_idx, true);
+        if ((err != REG_NOERROR))
+            return err;
+
+        if (dfa->eclosures[node_idx].nelem == 0) {
+            incomplete = true;
+            re_node_set_free(&eclosure_elem);
+        }
+    }
+    return REG_NOERROR;
+}
+
+/* Calculate epsilon closure of NODE.  */
+
+static reg_errcode_t
+calc_eclosure_iter(re_node_set *new_set, re_dfa_t *dfa, Idx node, bool root) {
+    reg_errcode_t err;
+    Idx i;
+    re_node_set eclosure;
+    bool ok;
+    bool incomplete = false;
+    err = re_node_set_alloc(&eclosure, dfa->edests[node].nelem + 1);
+    if ((err != REG_NOERROR))
+        return err;
+
+    /* This indicates that we are calculating this node now.
+       We reference this value to avoid infinite loop.  */
+    dfa->eclosures[node].nelem = -1;
+
+    /* If the current node has constraints, duplicate all nodes
+       since they must inherit the constraints.  */
+    if (dfa->nodes[node].constraint
+        && dfa->edests[node].nelem
+        && !dfa->nodes[dfa->edests[node].elems[0]].duplicated) {
+        err = duplicate_node_closure(dfa, node, node, node,
+                                     dfa->nodes[node].constraint);
+        if ((err != REG_NOERROR))
+            return err;
+    }
+
+    /* Expand each epsilon destination nodes.  */
+    if (IS_EPSILON_NODE(dfa->nodes[node].type))
+        for (i = 0; i < dfa->edests[node].nelem; ++i) {
+            re_node_set eclosure_elem;
+            Idx edest = dfa->edests[node].elems[i];
+            /* If calculating the epsilon closure of 'edest' is in progress,
+               return intermediate result.  */
+            if (dfa->eclosures[edest].nelem == -1) {
+                incomplete = true;
+                continue;
+            }
+            /* If we haven't calculated the epsilon closure of 'edest' yet,
+               calculate now. Otherwise use calculated epsilon closure.  */
+            if (dfa->eclosures[edest].nelem == 0) {
+                err = calc_eclosure_iter(&eclosure_elem, dfa, edest, false);
+                if ((err != REG_NOERROR))
+                    return err;
+            } else
+                eclosure_elem = dfa->eclosures[edest];
+            /* Merge the epsilon closure of 'edest'.  */
+            err = re_node_set_merge(&eclosure, &eclosure_elem);
+            if ((err != REG_NOERROR))
+                return err;
+            /* If the epsilon closure of 'edest' is incomplete,
+               the epsilon closure of this node is also incomplete.  */
+            if (dfa->eclosures[edest].nelem == 0) {
+                incomplete = true;
+                re_node_set_free(&eclosure_elem);
+            }
+        }
+
+    /* An epsilon closure includes itself.  */
+    ok = re_node_set_insert(&eclosure, node);
+    if ((!ok))
+        return REG_ESPACE;
+    if (incomplete && !root)
+        dfa->eclosures[node].nelem = 0;
+    else
+        dfa->eclosures[node] = eclosure;
+    *new_set = eclosure;
+    return REG_NOERROR;
+}
+
+/* Functions for token which are used in the parser.  */
+
+/* Fetch a token from INPUT.
+   We must not use this function inside bracket expressions.  */
+
+static void
+fetch_token(re_token_t *result, re_string_t *input, reg_syntax_t syntax) {
+    re_string_skip_bytes(input, peek_token(result, input, syntax));
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function inside bracket expressions.  */
+
+static int
+peek_token(re_token_t *token, re_string_t *input, reg_syntax_t syntax) {
+    unsigned char c;
+
+    if (re_string_eoi(input)) {
+        token->type = END_OF_RE;
+        return 0;
+    }
+
+    c = re_string_peek_byte(input, 0);
+    token->opr.c = c;
+
+    token->word_char = 0;
+
+    if (c == '\\') {
+        unsigned char c2;
+        if (re_string_cur_idx(input) + 1 >= re_string_length(input)) {
+            token->type = BACK_SLASH;
+            return 1;
+        }
+
+        c2 = re_string_peek_byte_case(input, 1);
+        token->opr.c = c2;
+        token->type = CHARACTER;
+
+        token->word_char = IS_WORD_CHAR(c2) != 0;
+
+        switch (c2) {
+            case '|':
+                if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_NO_BK_VBAR))
+                    token->type = OP_ALT;
+                break;
+            case '1':
+            case '2':
+            case '3':
+            case '4':
+            case '5':
+            case '6':
+            case '7':
+            case '8':
+            case '9':
+                if (!(syntax & RE_NO_BK_REFS)) {
+                    token->type = OP_BACK_REF;
+                    token->opr.idx = c2 - '1';
+                }
+                break;
+            case '<':
+                if (!(syntax & RE_NO_GNU_OPS)) {
+                    token->type = ANCHOR;
+                    token->opr.ctx_type = WORD_FIRST;
+                }
+                break;
+            case '>':
+                if (!(syntax & RE_NO_GNU_OPS)) {
+                    token->type = ANCHOR;
+                    token->opr.ctx_type = WORD_LAST;
+                }
+                break;
+            case 'b':
+                if (!(syntax & RE_NO_GNU_OPS)) {
+                    token->type = ANCHOR;
+                    token->opr.ctx_type = WORD_DELIM;
+                }
+                break;
+            case 'B':
+                if (!(syntax & RE_NO_GNU_OPS)) {
+                    token->type = ANCHOR;
+                    token->opr.ctx_type = NOT_WORD_DELIM;
+                }
+                break;
+            case 'w':
+                if (!(syntax & RE_NO_GNU_OPS))
+                    token->type = OP_WORD;
+                break;
+            case 'W':
+                if (!(syntax & RE_NO_GNU_OPS))
+                    token->type = OP_NOTWORD;
+                break;
+            case 's':
+                if (!(syntax & RE_NO_GNU_OPS))
+                    token->type = OP_SPACE;
+                break;
+            case 'S':
+                if (!(syntax & RE_NO_GNU_OPS))
+                    token->type = OP_NOTSPACE;
+                break;
+            case '`':
+                if (!(syntax & RE_NO_GNU_OPS)) {
+                    token->type = ANCHOR;
+                    token->opr.ctx_type = BUF_FIRST;
+                }
+                break;
+            case '\'':
+                if (!(syntax & RE_NO_GNU_OPS)) {
+                    token->type = ANCHOR;
+                    token->opr.ctx_type = BUF_LAST;
+                }
+                break;
+            case '(':
+                if (!(syntax & RE_NO_BK_PARENS))
+                    token->type = OP_OPEN_SUBEXP;
+                break;
+            case ')':
+                if (!(syntax & RE_NO_BK_PARENS))
+                    token->type = OP_CLOSE_SUBEXP;
+                break;
+            case '+':
+                if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+                    token->type = OP_DUP_PLUS;
+                break;
+            case '?':
+                if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_BK_PLUS_QM))
+                    token->type = OP_DUP_QUESTION;
+                break;
+            case '{':
+                if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+                    token->type = OP_OPEN_DUP_NUM;
+                break;
+            case '}':
+                if ((syntax & RE_INTERVALS) && (!(syntax & RE_NO_BK_BRACES)))
+                    token->type = OP_CLOSE_DUP_NUM;
+                break;
+            default:
+                break;
+        }
+        return 2;
+    }
+
+    token->type = CHARACTER;
+
+    token->word_char = IS_WORD_CHAR(token->opr.c);
+
+    switch (c) {
+        case '\n':
+            if (syntax & RE_NEWLINE_ALT)
+                token->type = OP_ALT;
+            break;
+        case '|':
+            if (!(syntax & RE_LIMITED_OPS) && (syntax & RE_NO_BK_VBAR))
+                token->type = OP_ALT;
+            break;
+        case '*':
+            token->type = OP_DUP_ASTERISK;
+            break;
+        case '+':
+            if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+                token->type = OP_DUP_PLUS;
+            break;
+        case '?':
+            if (!(syntax & RE_LIMITED_OPS) && !(syntax & RE_BK_PLUS_QM))
+                token->type = OP_DUP_QUESTION;
+            break;
+        case '{':
+            if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+                token->type = OP_OPEN_DUP_NUM;
+            break;
+        case '}':
+            if ((syntax & RE_INTERVALS) && (syntax & RE_NO_BK_BRACES))
+                token->type = OP_CLOSE_DUP_NUM;
+            break;
+        case '(':
+            if (syntax & RE_NO_BK_PARENS)
+                token->type = OP_OPEN_SUBEXP;
+            break;
+        case ')':
+            if (syntax & RE_NO_BK_PARENS)
+                token->type = OP_CLOSE_SUBEXP;
+            break;
+        case '[':
+            token->type = OP_OPEN_BRACKET;
+            break;
+        case '.':
+            token->type = OP_PERIOD;
+            break;
+        case '^':
+            if (!(syntax & (RE_CONTEXT_INDEP_ANCHORS | RE_CARET_ANCHORS_HERE)) &&
+                re_string_cur_idx(input) != 0) {
+                char prev = re_string_peek_byte(input, -1);
+                if (!(syntax & RE_NEWLINE_ALT) || prev != '\n')
+                    break;
+            }
+            token->type = ANCHOR;
+            token->opr.ctx_type = LINE_FIRST;
+            break;
+        case '$':
+            if (!(syntax & RE_CONTEXT_INDEP_ANCHORS) &&
+                re_string_cur_idx(input) + 1 != re_string_length(input)) {
+                re_token_t next;
+                re_string_skip_bytes(input, 1);
+                peek_token(&next, input, syntax);
+                re_string_skip_bytes(input, -1);
+                if (next.type != OP_ALT && next.type != OP_CLOSE_SUBEXP)
+                    break;
+            }
+            token->type = ANCHOR;
+            token->opr.ctx_type = LINE_LAST;
+            break;
+        default:
+            break;
+    }
+    return 1;
+}
+
+/* Peek a token from INPUT, and return the length of the token.
+   We must not use this function out of bracket expressions.  */
+
+static int
+peek_token_bracket(re_token_t *token, re_string_t *input, reg_syntax_t syntax) {
+    unsigned char c;
+    if (re_string_eoi(input)) {
+        token->type = END_OF_RE;
+        return 0;
+    }
+    c = re_string_peek_byte(input, 0);
+    token->opr.c = c;
+
+    if (c == '\\' && (syntax & RE_BACKSLASH_ESCAPE_IN_LISTS)
+        && re_string_cur_idx(input) + 1 < re_string_length(input)) {
+        /* In this case, '\' escape a character.  */
+        unsigned char c2;
+        re_string_skip_bytes(input, 1);
+        c2 = re_string_peek_byte(input, 0);
+        token->opr.c = c2;
+        token->type = CHARACTER;
+        return 1;
+    }
+    if (c == '[') /* '[' is a special char in a bracket exps.  */
+    {
+        unsigned char c2;
+        int token_len;
+        if (re_string_cur_idx(input) + 1 < re_string_length(input))
+            c2 = re_string_peek_byte(input, 1);
+        else
+            c2 = 0;
+        token->opr.c = c2;
+        token_len = 2;
+        switch (c2) {
+            case '.':
+                token->type = OP_OPEN_COLL_ELEM;
+                break;
+
+            case '=':
+                token->type = OP_OPEN_EQUIV_CLASS;
+                break;
+
+            case ':':
+                if (syntax & RE_CHAR_CLASSES) {
+                    token->type = OP_OPEN_CHAR_CLASS;
+                    break;
+                }
+                FALLTHROUGH;
+            default:
+                token->type = CHARACTER;
+                token->opr.c = c;
+                token_len = 1;
+                break;
+        }
+        return token_len;
+    }
+    switch (c) {
+        case '-':
+            token->type = OP_CHARSET_RANGE;
+            break;
+        case ']':
+            token->type = OP_CLOSE_BRACKET;
+            break;
+        case '^':
+            token->type = OP_NON_MATCH_LIST;
+            break;
+        default:
+            token->type = CHARACTER;
+    }
+    return 1;
+}
+
+/* Functions for parser.  */
+
+/* Entry point of the parser.
+   Parse the regular expression REGEXP and return the structure tree.
+   If an error occurs, ERR is set by error code, and return NULL.
+   This function build the following tree, from regular expression <reg_exp>:
+	   CAT
+	   / \
+	  /   \
+   <reg_exp>  EOR
+
+   CAT means concatenation.
+   EOR means end of regular expression.  */
+
+static bin_tree_t *
+parse(re_string_t *regexp, regex_t *preg, reg_syntax_t syntax,
+      reg_errcode_t *err) {
+    re_dfa_t *dfa = preg->buffer;
+    bin_tree_t *tree, *eor, *root;
+    re_token_t current_token;
+    dfa->syntax = syntax;
+    fetch_token(&current_token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+    tree = parse_reg_exp(regexp, preg, &current_token, syntax, 0, err);
+    if ((*err != REG_NOERROR && tree == NULL))
+        return NULL;
+    eor = create_tree(dfa, NULL, NULL, END_OF_RE);
+    if (tree != NULL)
+        root = create_tree(dfa, tree, eor, CONCAT);
+    else
+        root = eor;
+    if ((eor == NULL || root == NULL)) {
+        *err = REG_ESPACE;
+        return NULL;
+    }
+    return root;
+}
+
+/* This function build the following tree, from regular expression
+   <branch1>|<branch2>:
+	   ALT
+	   / \
+	  /   \
+   <branch1> <branch2>
+
+   ALT means alternative, which represents the operator '|'.  */
+
+static bin_tree_t *
+parse_reg_exp(re_string_t *regexp, regex_t *preg, re_token_t *token,
+              reg_syntax_t syntax, Idx nest, reg_errcode_t *err) {
+    re_dfa_t *dfa = preg->buffer;
+    bin_tree_t *tree, *branch = NULL;
+    bitset_word_t initial_bkref_map = dfa->completed_bkref_map;
+    tree = parse_branch(regexp, preg, token, syntax, nest, err);
+    if ((*err != REG_NOERROR && tree == NULL))
+        return NULL;
+
+    while (token->type == OP_ALT) {
+        fetch_token(token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+        if (token->type != OP_ALT && token->type != END_OF_RE
+            && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) {
+            bitset_word_t accumulated_bkref_map = dfa->completed_bkref_map;
+            dfa->completed_bkref_map = initial_bkref_map;
+            branch = parse_branch(regexp, preg, token, syntax, nest, err);
+            if ((*err != REG_NOERROR && branch == NULL)) {
+                if (tree != NULL)
+                    postorder(tree, free_tree, NULL);
+                return NULL;
+            }
+            dfa->completed_bkref_map |= accumulated_bkref_map;
+        } else
+            branch = NULL;
+        tree = create_tree(dfa, tree, branch, OP_ALT);
+        if ((tree == NULL)) {
+            *err = REG_ESPACE;
+            return NULL;
+        }
+    }
+    return tree;
+}
+
+/* This function build the following tree, from regular expression
+   <exp1><exp2>:
+	CAT
+	/ \
+       /   \
+   <exp1> <exp2>
+
+   CAT means concatenation.  */
+
+static bin_tree_t *
+parse_branch(re_string_t *regexp, regex_t *preg, re_token_t *token,
+             reg_syntax_t syntax, Idx nest, reg_errcode_t *err) {
+    bin_tree_t *tree, *expr;
+    re_dfa_t *dfa = preg->buffer;
+    tree = parse_expression(regexp, preg, token, syntax, nest, err);
+    if ((*err != REG_NOERROR && tree == NULL))
+        return NULL;
+
+    while (token->type != OP_ALT && token->type != END_OF_RE
+           && (nest == 0 || token->type != OP_CLOSE_SUBEXP)) {
+        expr = parse_expression(regexp, preg, token, syntax, nest, err);
+        if ((*err != REG_NOERROR && expr == NULL)) {
+            if (tree != NULL)
+                postorder(tree, free_tree, NULL);
+            return NULL;
+        }
+        if (tree != NULL && expr != NULL) {
+            bin_tree_t *newtree = create_tree(dfa, tree, expr, CONCAT);
+            if (newtree == NULL) {
+                postorder(expr, free_tree, NULL);
+                postorder(tree, free_tree, NULL);
+                *err = REG_ESPACE;
+                return NULL;
+            }
+            tree = newtree;
+        } else if (tree == NULL)
+            tree = expr;
+        /* Otherwise expr == NULL, we don't need to create new tree.  */
+    }
+    return tree;
+}
+
+/* This function build the following tree, from regular expression a*:
+	 *
+	 |
+	 a
+*/
+
+static bin_tree_t *
+parse_expression(re_string_t *regexp, regex_t *preg, re_token_t *token,
+                 reg_syntax_t syntax, Idx nest, reg_errcode_t *err) {
+    re_dfa_t *dfa = preg->buffer;
+    bin_tree_t *tree;
+    switch (token->type) {
+        case CHARACTER:
+            tree = create_token_tree(dfa, NULL, NULL, token);
+            if ((tree == NULL)) {
+                *err = REG_ESPACE;
+                return NULL;
+            }
+            break;
+
+        case OP_OPEN_SUBEXP:
+            tree = parse_sub_exp(regexp, preg, token, syntax, nest + 1, err);
+            if ((*err != REG_NOERROR && tree == NULL))
+                return NULL;
+            break;
+
+        case OP_OPEN_BRACKET:
+            tree = parse_bracket_exp(regexp, dfa, token, syntax, err);
+            if ((*err != REG_NOERROR && tree == NULL))
+                return NULL;
+            break;
+
+        case OP_BACK_REF:
+            if (!(dfa->completed_bkref_map & (1 << token->opr.idx))) {
+                *err = REG_ESUBREG;
+                return NULL;
+            }
+            dfa->used_bkref_map |= 1 << token->opr.idx;
+            tree = create_token_tree(dfa, NULL, NULL, token);
+            if ((tree == NULL)) {
+                *err = REG_ESPACE;
+                return NULL;
+            }
+            ++dfa->nbackref;
+            dfa->has_mb_node = 1;
+            break;
+
+        case OP_OPEN_DUP_NUM:
+            if (syntax & RE_CONTEXT_INVALID_DUP) {
+                *err = REG_BADRPT;
+                return NULL;
+            }
+            FALLTHROUGH;
+        case OP_DUP_ASTERISK:
+        case OP_DUP_PLUS:
+        case OP_DUP_QUESTION:
+            if (syntax & RE_CONTEXT_INVALID_OPS) {
+                *err = REG_BADRPT;
+                return NULL;
+            } else if (syntax & RE_CONTEXT_INDEP_OPS) {
+                fetch_token(token, regexp, syntax);
+                return parse_expression(regexp, preg, token, syntax, nest, err);
+            }
+            FALLTHROUGH;
+        case OP_CLOSE_SUBEXP:
+            if ((token->type == OP_CLOSE_SUBEXP) &&
+                !(syntax & RE_UNMATCHED_RIGHT_PAREN_ORD)) {
+                *err = REG_ERPAREN;
+                return NULL;
+            }
+            FALLTHROUGH;
+        case OP_CLOSE_DUP_NUM:
+            /* We treat it as a normal character.  */
+
+            /* Then we can these characters as normal characters.  */
+            token->type = CHARACTER;
+            /* mb_partial and word_char bits should be initialized already
+           by peek_token.  */
+            tree = create_token_tree(dfa, NULL, NULL, token);
+            if ((tree == NULL)) {
+                *err = REG_ESPACE;
+                return NULL;
+            }
+            break;
+
+        case ANCHOR:
+            if ((token->opr.ctx_type
+                 & (WORD_DELIM | NOT_WORD_DELIM | WORD_FIRST | WORD_LAST))
+                && dfa->word_ops_used == 0)
+                init_word_char(dfa);
+            if (token->opr.ctx_type == WORD_DELIM
+                || token->opr.ctx_type == NOT_WORD_DELIM) {
+                bin_tree_t *tree_first, *tree_last;
+                if (token->opr.ctx_type == WORD_DELIM) {
+                    token->opr.ctx_type = WORD_FIRST;
+                    tree_first = create_token_tree(dfa, NULL, NULL, token);
+                    token->opr.ctx_type = WORD_LAST;
+                } else {
+                    token->opr.ctx_type = INSIDE_WORD;
+                    tree_first = create_token_tree(dfa, NULL, NULL, token);
+                    token->opr.ctx_type = INSIDE_NOTWORD;
+                }
+                tree_last = create_token_tree(dfa, NULL, NULL, token);
+                tree = create_tree(dfa, tree_first, tree_last, OP_ALT);
+                if ((tree_first == NULL || tree_last == NULL
+                     || tree == NULL)) {
+                    *err = REG_ESPACE;
+                    return NULL;
+                }
+            } else {
+                tree = create_token_tree(dfa, NULL, NULL, token);
+                if ((tree == NULL)) {
+                    *err = REG_ESPACE;
+                    return NULL;
+                }
+            }
+            /* We must return here, since ANCHORs can't be followed
+           by repetition operators.
+           eg. RE"^*" is invalid or "<ANCHOR(^)><CHAR(*)>",
+               it must not be "<ANCHOR(^)><REPEAT(*)>".  */
+            fetch_token(token, regexp, syntax);
+            return tree;
+
+        case OP_PERIOD:
+            tree = create_token_tree(dfa, NULL, NULL, token);
+            if ((tree == NULL)) {
+                *err = REG_ESPACE;
+                return NULL;
+            }
+            if (dfa->mb_cur_max > 1)
+                dfa->has_mb_node = 1;
+            break;
+
+        case OP_WORD:
+        case OP_NOTWORD:
+            tree = build_charclass_op(dfa, regexp->trans,
+                                      "alnum",
+                                      "_",
+                                      token->type == OP_NOTWORD, err);
+            if ((*err != REG_NOERROR && tree == NULL))
+                return NULL;
+            break;
+
+        case OP_SPACE:
+        case OP_NOTSPACE:
+            tree = build_charclass_op(dfa, regexp->trans,
+                                      "space",
+                                      "",
+                                      token->type == OP_NOTSPACE, err);
+            if ((*err != REG_NOERROR && tree == NULL))
+                return NULL;
+            break;
+
+        case OP_ALT:
+        case END_OF_RE:
+            return NULL;
+
+        case BACK_SLASH:
+            *err = REG_EESCAPE;
+            return NULL;
+
+        default:
+            /* Must not happen?  */
+            return NULL;
+    }
+    fetch_token(token, regexp, syntax);
+
+    while (token->type == OP_DUP_ASTERISK || token->type == OP_DUP_PLUS
+           || token->type == OP_DUP_QUESTION || token->type == OP_OPEN_DUP_NUM) {
+        bin_tree_t *dup_tree = parse_dup_op(tree, regexp, dfa, token,
+                                            syntax, err);
+        if ((*err != REG_NOERROR && dup_tree == NULL)) {
+            if (tree != NULL)
+                postorder(tree, free_tree, NULL);
+            return NULL;
+        }
+        tree = dup_tree;
+        /* In BRE consecutive duplications are not allowed.  */
+        if ((syntax & RE_CONTEXT_INVALID_DUP)
+            && (token->type == OP_DUP_ASTERISK
+                || token->type == OP_OPEN_DUP_NUM)) {
+            if (tree != NULL)
+                postorder(tree, free_tree, NULL);
+            *err = REG_BADRPT;
+            return NULL;
+        }
+    }
+
+    return tree;
+}
+
+/* This function build the following tree, from regular expression
+   (<reg_exp>):
+	 SUBEXP
+	    |
+	<reg_exp>
+*/
+
+static bin_tree_t *
+parse_sub_exp(re_string_t *regexp, regex_t *preg, re_token_t *token,
+              reg_syntax_t syntax, Idx nest, reg_errcode_t *err) {
+    re_dfa_t *dfa = preg->buffer;
+    bin_tree_t *tree;
+    size_t cur_nsub;
+    cur_nsub = preg->re_nsub++;
+
+    fetch_token(token, regexp, syntax | RE_CARET_ANCHORS_HERE);
+
+    /* The subexpression may be a null string.  */
+    if (token->type == OP_CLOSE_SUBEXP)
+        tree = NULL;
+    else {
+        tree = parse_reg_exp(regexp, preg, token, syntax, nest, err);
+        if ((*err == REG_NOERROR
+             && token->type != OP_CLOSE_SUBEXP)) {
+            if (tree != NULL)
+                postorder(tree, free_tree, NULL);
+            *err = REG_EPAREN;
+        }
+        if ((*err != REG_NOERROR))
+            return NULL;
+    }
+
+    if (cur_nsub <= '9' - '1')
+        dfa->completed_bkref_map |= 1 << cur_nsub;
+
+    tree = create_tree(dfa, tree, NULL, SUBEXP);
+    if ((tree == NULL)) {
+        *err = REG_ESPACE;
+        return NULL;
+    }
+    tree->token.opr.idx = cur_nsub;
+    return tree;
+}
+
+/* This function parse repetition operators like "*", "+", "{1,3}" etc.  */
+
+static bin_tree_t *
+parse_dup_op(bin_tree_t *elem, re_string_t *regexp, re_dfa_t *dfa,
+             re_token_t *token, reg_syntax_t syntax, reg_errcode_t *err) {
+    bin_tree_t *tree = NULL, *old_tree = NULL;
+    Idx i, start, end, start_idx = re_string_cur_idx(regexp);
+    re_token_t start_token = *token;
+
+    if (token->type == OP_OPEN_DUP_NUM) {
+        end = 0;
+        start = fetch_number(regexp, token, syntax);
+        if (start == -1) {
+            if (token->type == CHARACTER && token->opr.c == ',')
+                start = 0; /* We treat "{,m}" as "{0,m}".  */
+            else {
+                *err = REG_BADBR; /* <re>{} is invalid.  */
+                return NULL;
+            }
+        }
+        if ((start != -2)) {
+            /* We treat "{n}" as "{n,n}".  */
+            end = ((token->type == OP_CLOSE_DUP_NUM) ? start
+                                                     : ((token->type == CHARACTER && token->opr.c == ',')
+                                                        ? fetch_number(regexp, token, syntax) : -2));
+        }
+        if ((start == -2 || end == -2)) {
+            /* Invalid sequence.  */
+            if ((!(syntax & RE_INVALID_INTERVAL_ORD))) {
+                if (token->type == END_OF_RE)
+                    *err = REG_EBRACE;
+                else
+                    *err = REG_BADBR;
+
+                return NULL;
+            }
+
+            /* If the syntax bit is set, rollback.  */
+            re_string_set_index(regexp, start_idx);
+            *token = start_token;
+            token->type = CHARACTER;
+            /* mb_partial and word_char bits should be already initialized by
+               peek_token.  */
+            return elem;
+        }
+
+        if (((end != -1 && start > end)
+             || token->type != OP_CLOSE_DUP_NUM)) {
+            /* First number greater than second.  */
+            *err = REG_BADBR;
+            return NULL;
+        }
+
+        if ((RE_DUP_MAX < (end == -1 ? start : end))) {
+            *err = REG_ESIZE;
+            return NULL;
+        }
+    } else {
+        start = (token->type == OP_DUP_PLUS) ? 1 : 0;
+        end = (token->type == OP_DUP_QUESTION) ? 1 : -1;
+    }
+
+    fetch_token(token, regexp, syntax);
+
+    if ((elem == NULL))
+        return NULL;
+    if ((start == 0 && end == 0)) {
+        postorder(elem, free_tree, NULL);
+        return NULL;
+    }
+
+    /* Extract "<re>{n,m}" to "<re><re>...<re><re>{0,<m-n>}".  */
+    if ((start > 0)) {
+        tree = elem;
+        for (i = 2; i <= start; ++i) {
+            elem = duplicate_tree(elem, dfa);
+            tree = create_tree(dfa, tree, elem, CONCAT);
+            if ((elem == NULL || tree == NULL))
+                goto parse_dup_op_espace;
+        }
+
+        if (start == end)
+            return tree;
+
+        /* Duplicate ELEM before it is marked optional.  */
+        elem = duplicate_tree(elem, dfa);
+        if ((elem == NULL))
+            goto parse_dup_op_espace;
+        old_tree = tree;
+    } else
+        old_tree = NULL;
+
+    if (elem->token.type == SUBEXP) {
+        uintptr_t subidx = elem->token.opr.idx;
+        postorder(elem, mark_opt_subexp, (void *) subidx);
+    }
+
+    tree = create_tree(dfa, elem, NULL,
+                       (end == -1 ? OP_DUP_ASTERISK : OP_ALT));
+    if ((tree == NULL))
+        goto parse_dup_op_espace;
+
+    /* This loop is actually executed only when end != -1,
+       to rewrite <re>{0,n} as (<re>(<re>...<re>?)?)?...  We have
+       already created the start+1-th copy.  */
+    if (TYPE_SIGNED(Idx) || end != -1)
+        for (i = start + 2; i <= end; ++i) {
+            elem = duplicate_tree(elem, dfa);
+            tree = create_tree(dfa, tree, elem, CONCAT);
+            if ((elem == NULL || tree == NULL))
+                goto parse_dup_op_espace;
+
+            tree = create_tree(dfa, tree, NULL, OP_ALT);
+            if ((tree == NULL))
+                goto parse_dup_op_espace;
+        }
+
+    if (old_tree)
+        tree = create_tree(dfa, old_tree, tree, CONCAT);
+
+    return tree;
+
+    parse_dup_op_espace:
+    *err = REG_ESPACE;
+    return NULL;
+}
+
+/* Size of the names for collating symbol/equivalence_class/character_class.
+   I'm not sure, but maybe enough.  */
+#define BRACKET_NAME_BUF_SIZE 32
+
+/* Local function for parse_bracket_exp only used in case of NOT _LIBC.
+   Build the range expression which starts from START_ELEM, and ends
+   at END_ELEM.  The result are written to MBCSET and SBCSET.
+   RANGE_ALLOC is the allocated size of mbcset->range_starts, and
+   mbcset->range_ends, is a pointer argument since we may
+   update it.  */
+
+static reg_errcode_t
+build_range_exp(const reg_syntax_t syntax,
+                bitset_t sbcset,
+                const bracket_elem_t *start_elem,
+                const bracket_elem_t *end_elem) {
+    unsigned int start_ch, end_ch;
+    /* Equivalence Classes and Character Classes can't be a range start/end.  */
+    if ((start_elem->type == EQUIV_CLASS
+         || start_elem->type == CHAR_CLASS
+         || end_elem->type == EQUIV_CLASS
+         || end_elem->type == CHAR_CLASS))
+        return REG_ERANGE;
+
+    /* We can handle no multi character collating elements without libc
+       support.  */
+    if (((start_elem->type == COLL_SYM
+          && strlen((char *) start_elem->opr.name) > 1)
+         || (end_elem->type == COLL_SYM
+             && strlen((char *) end_elem->opr.name) > 1)))
+        return REG_ECOLLATE;
+
+    {
+        unsigned int ch;
+        start_ch = ((start_elem->type == SB_CHAR) ? start_elem->opr.ch
+                                                  : ((start_elem->type == COLL_SYM) ? start_elem->opr.name[0]
+                                                                                    : 0));
+        end_ch = ((end_elem->type == SB_CHAR) ? end_elem->opr.ch
+                                              : ((end_elem->type == COLL_SYM) ? end_elem->opr.name[0]
+                                                                              : 0));
+        if (start_ch > end_ch)
+            return REG_ERANGE;
+        /* Build the table for single byte characters.  */
+        for (ch = 0; ch < SBC_MAX; ++ch)
+            if (start_ch <= ch && ch <= end_ch)
+                bitset_set(sbcset, ch);
+    }
+    return REG_NOERROR;
+}
+
+/* Helper function for parse_bracket_exp only used in case of NOT _LIBC..
+   Build the collating element which is represented by NAME.
+   The result are written to MBCSET and SBCSET.
+   COLL_SYM_ALLOC is the allocated size of mbcset->coll_sym, is a
+   pointer argument since we may update it.  */
+
+static reg_errcode_t
+build_collating_symbol(bitset_t sbcset, const unsigned char *name) {
+    size_t name_len = strlen((const char *) name);
+    if ((name_len != 1))
+        return REG_ECOLLATE;
+    else {
+        bitset_set(sbcset, name[0]);
+        return REG_NOERROR;
+    }
+}
+
+
+/* This function parse bracket expression like "[abc]", "[a-c]",
+   "[[.a-a.]]" etc.  */
+
+static bin_tree_t *
+parse_bracket_exp(re_string_t *regexp, re_dfa_t *dfa, re_token_t *token,
+                  reg_syntax_t syntax, reg_errcode_t *err) {
+    re_token_t br_token;
+    re_bitset_ptr_t sbcset;
+    bool non_match = false;
+    bin_tree_t *work_tree;
+    int token_len;
+    bool first_round = true;
+    sbcset = (re_bitset_ptr_t) calloc(sizeof(bitset_t), 1);
+    if ((sbcset == NULL)) {
+        re_free(sbcset);
+        *err = REG_ESPACE;
+        return NULL;
+    }
+
+    token_len = peek_token_bracket(token, regexp, syntax);
+    if ((token->type == END_OF_RE)) {
+        *err = REG_BADPAT;
+        goto parse_bracket_exp_free_return;
+    }
+    if (token->type == OP_NON_MATCH_LIST) {
+        non_match = true;
+        if (syntax & RE_HAT_LISTS_NOT_NEWLINE)
+            bitset_set(sbcset, '\n');
+        re_string_skip_bytes(regexp, token_len); /* Skip a token.  */
+        token_len = peek_token_bracket(token, regexp, syntax);
+        if ((token->type == END_OF_RE)) {
+            *err = REG_BADPAT;
+            goto parse_bracket_exp_free_return;
+        }
+    }
+
+    /* We treat the first ']' as a normal character.  */
+    if (token->type == OP_CLOSE_BRACKET)
+        token->type = CHARACTER;
+
+    while (1) {
+        bracket_elem_t start_elem, end_elem;
+        unsigned char start_name_buf[BRACKET_NAME_BUF_SIZE];
+        unsigned char end_name_buf[BRACKET_NAME_BUF_SIZE];
+        reg_errcode_t ret;
+        int token_len2 = 0;
+        bool is_range_exp = false;
+        re_token_t token2;
+
+        start_elem.opr.name = start_name_buf;
+        start_elem.type = COLL_SYM;
+        ret = parse_bracket_element(&start_elem, regexp, token, token_len, dfa,
+                                    syntax, first_round);
+        if ((ret != REG_NOERROR)) {
+            *err = ret;
+            goto parse_bracket_exp_free_return;
+        }
+        first_round = false;
+
+        /* Get information about the next token.  We need it in any case.  */
+        token_len = peek_token_bracket(token, regexp, syntax);
+
+        /* Do not check for ranges if we know they are not allowed.  */
+        if (start_elem.type != CHAR_CLASS && start_elem.type != EQUIV_CLASS) {
+            if ((token->type == END_OF_RE)) {
+                *err = REG_EBRACK;
+                goto parse_bracket_exp_free_return;
+            }
+            if (token->type == OP_CHARSET_RANGE) {
+                re_string_skip_bytes(regexp, token_len); /* Skip '-'.  */
+                token_len2 = peek_token_bracket(&token2, regexp, syntax);
+                if ((token2.type == END_OF_RE)) {
+                    *err = REG_EBRACK;
+                    goto parse_bracket_exp_free_return;
+                }
+                if (token2.type == OP_CLOSE_BRACKET) {
+                    /* We treat the last '-' as a normal character.  */
+                    re_string_skip_bytes(regexp, -token_len);
+                    token->type = CHARACTER;
+                } else
+                    is_range_exp = true;
+            }
+        }
+
+        if (is_range_exp == true) {
+            end_elem.opr.name = end_name_buf;
+            end_elem.type = COLL_SYM;
+            ret = parse_bracket_element(&end_elem, regexp, &token2, token_len2,
+                                        dfa, syntax, true);
+            if ((ret != REG_NOERROR)) {
+                *err = ret;
+                goto parse_bracket_exp_free_return;
+            }
+
+            token_len = peek_token_bracket(token, regexp, syntax);
+
+            *err = build_range_exp(syntax, sbcset, &start_elem, &end_elem);
+
+            if ((*err != REG_NOERROR))
+                goto parse_bracket_exp_free_return;
+        } else {
+            switch (start_elem.type) {
+                case SB_CHAR:
+                    bitset_set(sbcset, start_elem.opr.ch);
+                    break;
+                case EQUIV_CLASS:
+                    *err = build_equiv_class(sbcset,
+                                             start_elem.opr.name);
+                    if ((*err != REG_NOERROR))
+                        goto parse_bracket_exp_free_return;
+                    break;
+                case COLL_SYM:
+                    *err = build_collating_symbol(sbcset,
+                                                  start_elem.opr.name);
+                    if ((*err != REG_NOERROR))
+                        goto parse_bracket_exp_free_return;
+                    break;
+                case CHAR_CLASS:
+                    *err = build_charclass(regexp->trans, sbcset,
+                                           (const char *) start_elem.opr.name,
+                                           syntax);
+                    if ((*err != REG_NOERROR))
+                        goto parse_bracket_exp_free_return;
+                    break;
+                default:
+                    assert(0);
+                    break;
+            }
+        }
+        if ((token->type == END_OF_RE)) {
+            *err = REG_EBRACK;
+            goto parse_bracket_exp_free_return;
+        }
+        if (token->type == OP_CLOSE_BRACKET)
+            break;
+    }
+
+    re_string_skip_bytes(regexp, token_len); /* Skip a token.  */
+
+    /* If it is non-matching list.  */
+    if (non_match)
+        bitset_not(sbcset);
+
+    {
+        /* Build a tree for simple bracket.  */
+        br_token.type = SIMPLE_BRACKET;
+        br_token.opr.sbcset = sbcset;
+        work_tree = create_token_tree(dfa, NULL, NULL, &br_token);
+        if ((work_tree == NULL))
+            goto parse_bracket_exp_espace;
+    }
+    return work_tree;
+
+    parse_bracket_exp_espace:
+    *err = REG_ESPACE;
+    parse_bracket_exp_free_return:
+    re_free(sbcset);
+    return NULL;
+}
+
+/* Parse an element in the bracket expression.  */
+
+static reg_errcode_t
+parse_bracket_element(bracket_elem_t *elem, re_string_t *regexp,
+                      re_token_t *token, int token_len, re_dfa_t *dfa,
+                      reg_syntax_t syntax, bool accept_hyphen) {
+    re_string_skip_bytes(regexp, token_len); /* Skip a token.  */
+    if (token->type == OP_OPEN_COLL_ELEM || token->type == OP_OPEN_CHAR_CLASS
+        || token->type == OP_OPEN_EQUIV_CLASS)
+        return parse_bracket_symbol(elem, regexp, token);
+    if ((token->type == OP_CHARSET_RANGE) && !accept_hyphen) {
+        /* A '-' must only appear as anything but a range indicator before
+       the closing bracket.  Everything else is an error.  */
+        re_token_t token2;
+        (void) peek_token_bracket(&token2, regexp, syntax);
+        if (token2.type != OP_CLOSE_BRACKET)
+            /* The actual error value is not standardized since this whole
+               case is undefined.  But ERANGE makes good sense.  */
+            return REG_ERANGE;
+    }
+    elem->type = SB_CHAR;
+    elem->opr.ch = token->opr.c;
+    return REG_NOERROR;
+}
+
+/* Parse a bracket symbol in the bracket expression.  Bracket symbols are
+   such as [:<character_class>:], [.<collating_element>.], and
+   [=<equivalent_class>=].  */
+
+static reg_errcode_t
+parse_bracket_symbol(bracket_elem_t *elem, re_string_t *regexp,
+                     re_token_t *token) {
+    unsigned char ch, delim = token->opr.c;
+    int i = 0;
+    if (re_string_eoi(regexp))
+        return REG_EBRACK;
+    for (;; ++i) {
+        if (i >= BRACKET_NAME_BUF_SIZE)
+            return REG_EBRACK;
+        if (token->type == OP_OPEN_CHAR_CLASS)
+            ch = re_string_fetch_byte_case(regexp);
+        else
+            ch = re_string_fetch_byte(regexp);
+        if (re_string_eoi(regexp))
+            return REG_EBRACK;
+        if (ch == delim && re_string_peek_byte(regexp, 0) == ']')
+            break;
+        elem->opr.name[i] = ch;
+    }
+    re_string_skip_bytes(regexp, 1);
+    elem->opr.name[i] = '\0';
+    switch (token->type) {
+        case OP_OPEN_COLL_ELEM:
+            elem->type = COLL_SYM;
+            break;
+        case OP_OPEN_EQUIV_CLASS:
+            elem->type = EQUIV_CLASS;
+            break;
+        case OP_OPEN_CHAR_CLASS:
+            elem->type = CHAR_CLASS;
+            break;
+        default:
+            break;
+    }
+    return REG_NOERROR;
+}
+
+/* Helper function for parse_bracket_exp.
+   Build the equivalence class which is represented by NAME.
+   The result are written to MBCSET and SBCSET.
+   EQUIV_CLASS_ALLOC is the allocated size of mbcset->equiv_classes,
+   is a pointer argument since we may update it.  */
+
+static reg_errcode_t
+build_equiv_class(bitset_t sbcset, const unsigned char *name) {
+    {
+        if ((strlen((const char *) name) != 1))
+            return REG_ECOLLATE;
+        bitset_set(sbcset, *name);
+    }
+    return REG_NOERROR;
+}
+
+/* Helper function for parse_bracket_exp.
+   Build the character class which is represented by NAME.
+   The result are written to MBCSET and SBCSET.
+   CHAR_CLASS_ALLOC is the allocated size of mbcset->char_classes,
+   is a pointer argument since we may update it.  */
+
+static reg_errcode_t
+build_charclass(RE_TRANSLATE_TYPE trans, bitset_t sbcset,
+                const char *class_name, reg_syntax_t syntax) {
+    int i;
+    const char *name = class_name;
+
+    /* In case of REG_ICASE "upper" and "lower" match the both of
+       upper and lower cases.  */
+    if ((syntax & RE_ICASE)
+        && (strcmp(name, "upper") == 0 || strcmp(name, "lower") == 0))
+        name = "alpha";
+
+#define BUILD_CHARCLASS_LOOP(ctype_func)    \
+  do {                        \
+    if ( (trans != NULL))            \
+      {                        \
+    for (i = 0; i < SBC_MAX; ++i)        \
+      if (ctype_func (i))            \
+        bitset_set (sbcset, trans[i]);    \
+      }                        \
+    else                    \
+      {                        \
+    for (i = 0; i < SBC_MAX; ++i)        \
+      if (ctype_func (i))            \
+        bitset_set (sbcset, i);        \
+      }                        \
+  } while (0)
+
+    if (strcmp(name, "alnum") == 0)
+        BUILD_CHARCLASS_LOOP (isalnum);
+    else if (strcmp(name, "cntrl") == 0)
+        BUILD_CHARCLASS_LOOP (iscntrl);
+    else if (strcmp(name, "lower") == 0)
+        BUILD_CHARCLASS_LOOP (islower);
+    else if (strcmp(name, "space") == 0)
+        BUILD_CHARCLASS_LOOP (isspace);
+    else if (strcmp(name, "alpha") == 0)
+        BUILD_CHARCLASS_LOOP (isalpha);
+    else if (strcmp(name, "digit") == 0)
+        BUILD_CHARCLASS_LOOP (isdigit);
+    else if (strcmp(name, "print") == 0)
+        BUILD_CHARCLASS_LOOP (isprint);
+    else if (strcmp(name, "upper") == 0)
+        BUILD_CHARCLASS_LOOP (isupper);
+    else if (strcmp(name, "blank") == 0)
+        BUILD_CHARCLASS_LOOP (isblank);
+    else if (strcmp(name, "graph") == 0)
+        BUILD_CHARCLASS_LOOP (isgraph);
+    else if (strcmp(name, "punct") == 0)
+        BUILD_CHARCLASS_LOOP (ispunct);
+    else if (strcmp(name, "xdigit") == 0)
+        BUILD_CHARCLASS_LOOP (isxdigit);
+    else
+        return REG_ECTYPE;
+
+    return REG_NOERROR;
+}
+
+static bin_tree_t *
+build_charclass_op(re_dfa_t *dfa, RE_TRANSLATE_TYPE trans,
+                   const char *class_name,
+                   const char *extra, bool non_match,
+                   reg_errcode_t *err) {
+    re_bitset_ptr_t sbcset;
+    reg_errcode_t ret;
+    re_token_t br_token;
+    bin_tree_t *tree;
+
+    sbcset = (re_bitset_ptr_t) calloc(sizeof(bitset_t), 1);
+    if ((sbcset == NULL)) {
+        *err = REG_ESPACE;
+        return NULL;
+    }
+
+    /* We don't care the syntax in this case.  */
+    ret = build_charclass(trans, sbcset,
+                          class_name, 0);
+
+    if ((ret != REG_NOERROR)) {
+        re_free(sbcset);
+        *err = ret;
+        return NULL;
+    }
+    /* \w match '_' also.  */
+    for (; *extra; extra++)
+        bitset_set(sbcset, *extra);
+
+    /* If it is non-matching list.  */
+    if (non_match)
+        bitset_not(sbcset);
+
+    /* Build a tree for simple bracket.  */
+    br_token.type = SIMPLE_BRACKET;
+    br_token.opr.sbcset = sbcset;
+    tree = create_token_tree(dfa, NULL, NULL, &br_token);
+    if ((tree == NULL))
+        goto build_word_op_espace;
+
+    return tree;
+
+    build_word_op_espace:
+    re_free(sbcset);
+    *err = REG_ESPACE;
+    return NULL;
+}
+
+/* This is intended for the expressions like "a{1,3}".
+   Fetch a number from 'input', and return the number.
+   Return -1 if the number field is empty like "{,1}".
+   Return RE_DUP_MAX + 1 if the number field is too large.
+   Return -2 if an error occurred.  */
+
+static Idx
+fetch_number(re_string_t *input, re_token_t *token, reg_syntax_t syntax) {
+    Idx num = -1;
+    unsigned char c;
+    while (1) {
+        fetch_token(token, input, syntax);
+        c = token->opr.c;
+        if ((token->type == END_OF_RE))
+            return -2;
+        if (token->type == OP_CLOSE_DUP_NUM || c == ',')
+            break;
+        num = ((token->type != CHARACTER || c < '0' || '9' < c || num == -2)
+               ? -2
+               : num == -1
+                 ? c - '0'
+                 : MIN (RE_DUP_MAX + 1, num * 10 + c - '0'));
+    }
+    return num;
+}
+
+/* Functions for binary tree operation.  */
+
+/* Create a tree node.  */
+
+static bin_tree_t *
+create_tree(re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+            re_token_type_t type) {
+    re_token_t t;
+    t.type = type;
+    return create_token_tree(dfa, left, right, &t);
+}
+
+static bin_tree_t *
+create_token_tree(re_dfa_t *dfa, bin_tree_t *left, bin_tree_t *right,
+                  const re_token_t *token) {
+    bin_tree_t *tree;
+    if ((dfa->str_tree_storage_idx == BIN_TREE_STORAGE_SIZE)) {
+        bin_tree_storage_t *storage = re_malloc(bin_tree_storage_t, 1);
+
+        if (storage == NULL)
+            return NULL;
+        storage->next = dfa->str_tree_storage;
+        dfa->str_tree_storage = storage;
+        dfa->str_tree_storage_idx = 0;
+    }
+    tree = &dfa->str_tree_storage->data[dfa->str_tree_storage_idx++];
+
+    tree->parent = NULL;
+    tree->left = left;
+    tree->right = right;
+    tree->token = *token;
+    tree->token.duplicated = 0;
+    tree->token.opt_subexp = 0;
+    tree->first = NULL;
+    tree->next = NULL;
+    tree->node_idx = -1;
+
+    if (left != NULL)
+        left->parent = tree;
+    if (right != NULL)
+        right->parent = tree;
+    return tree;
+}
+
+/* Mark the tree SRC as an optional subexpression.
+   To be called from preorder or postorder.  */
+
+static reg_errcode_t
+mark_opt_subexp(void *extra, bin_tree_t *node) {
+    Idx idx = (uintptr_t) extra;
+    if (node->token.type == SUBEXP && node->token.opr.idx == idx)
+        node->token.opt_subexp = 1;
+
+    return REG_NOERROR;
+}
+
+/* Free the allocated memory inside NODE. */
+
+static void
+free_token(re_token_t *node) {
+    if (node->type == SIMPLE_BRACKET && node->duplicated == 0)
+        re_free(node->opr.sbcset);
+}
+
+/* Worker function for tree walking.  Free the allocated memory inside NODE
+   and its children. */
+
+static reg_errcode_t
+free_tree(void *extra, bin_tree_t *node) {
+    free_token(&node->token);
+    return REG_NOERROR;
+}
+
+
+/* Duplicate the node SRC, and return new node.  This is a preorder
+   visit similar to the one implemented by the generic visitor, but
+   we need more infrastructure to maintain two parallel trees --- so,
+   it's easier to duplicate.  */
+
+static bin_tree_t *
+duplicate_tree(const bin_tree_t *root, re_dfa_t *dfa) {
+    const bin_tree_t *node;
+    bin_tree_t *dup_root;
+    bin_tree_t **p_new = &dup_root, *dup_node = root->parent;
+
+    for (node = root;;) {
+        /* Create a new tree and link it back to the current parent.  */
+        *p_new = create_token_tree(dfa, NULL, NULL, &node->token);
+        if (*p_new == NULL)
+            return NULL;
+        (*p_new)->parent = dup_node;
+        (*p_new)->token.duplicated = 1;
+        dup_node = *p_new;
+
+        /* Go to the left node, or up and to the right.  */
+        if (node->left) {
+            node = node->left;
+            p_new = &dup_node->left;
+        } else {
+            const bin_tree_t *prev = NULL;
+            while (node->right == prev || node->right == NULL) {
+                prev = node;
+                node = node->parent;
+                dup_node = dup_node->parent;
+                if (!node)
+                    return dup_root;
+            }
+            node = node->right;
+            p_new = &dup_node->right;
+        }
+    }
+}
+
+static reg_errcode_t
+prune_impossible_nodes(re_match_context_t *mctx) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    Idx halt_node, match_last;
+    reg_errcode_t ret;
+    re_dfastate_t **sifted_states;
+    re_dfastate_t **lim_states = NULL;
+    re_sift_context_t sctx;
+    match_last = mctx->match_last;
+    halt_node = mctx->last_node;
+
+/* Avoid overflow.  */
+    if ((MIN (IDX_MAX, SIZE_MAX / sizeof(re_dfastate_t * ))
+         <= match_last))
+        return REG_ESPACE;
+
+    sifted_states = re_malloc(re_dfastate_t * , match_last + 1);
+    if ((sifted_states == NULL)) {
+        ret = REG_ESPACE;
+        goto free_return;
+    }
+    if (dfa->nbackref) {
+        lim_states = re_malloc(re_dfastate_t * , match_last + 1);
+        if ((lim_states == NULL)) {
+            ret = REG_ESPACE;
+            goto free_return;
+        }
+        while (1) {
+            memset(lim_states, '\0',
+                   sizeof(re_dfastate_t * ) * (match_last + 1));
+            sift_ctx_init(&sctx, sifted_states, lim_states, halt_node,
+                          match_last);
+            ret = sift_states_backward(mctx, &sctx);
+            re_node_set_free(&sctx.limits);
+            if ((ret != REG_NOERROR))
+                goto free_return;
+            if (sifted_states[0] != NULL || lim_states[0] != NULL)
+                break;
+            do {
+                --match_last;
+                if (match_last < 0) {
+                    ret = REG_NOMATCH;
+                    goto free_return;
+                }
+            } while (mctx->state_log[match_last] == NULL
+                     || !mctx->state_log[match_last]->halt);
+            halt_node = check_halt_state_context(mctx,
+                                                 mctx->state_log[match_last],
+                                                 match_last);
+        }
+        ret = merge_state_array(dfa, sifted_states, lim_states,
+                                match_last + 1);
+        re_free(lim_states);
+        lim_states = NULL;
+        if ((ret != REG_NOERROR))
+            goto free_return;
+    } else {
+        sift_ctx_init(&sctx, sifted_states, lim_states, halt_node, match_last);
+        ret = sift_states_backward(mctx, &sctx);
+        re_node_set_free(&sctx.limits);
+        if ((ret != REG_NOERROR))
+            goto free_return;
+        if (sifted_states[0] == NULL) {
+            ret = REG_NOMATCH;
+            goto free_return;
+        }
+    }
+    re_free(mctx->state_log);
+    mctx->state_log = sifted_states;
+    sifted_states = NULL;
+    mctx->last_node = halt_node;
+    mctx->match_last = match_last;
+    ret = REG_NOERROR;
+    free_return:
+    re_free(sifted_states);
+    re_free(lim_states);
+    return ret;
+}
+
+/* Acquire an initial state and return it.
+   We must select appropriate initial state depending on the context,
+   since initial states may have constraints like "\<", "^", etc..  */
+
+static inline re_dfastate_t *
+acquire_init_state_context(reg_errcode_t *err, const re_match_context_t *mctx,
+                           Idx idx) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    if (dfa->init_state->has_constraint) {
+        unsigned int context;
+        context = re_string_context_at(&mctx->input, idx - 1, mctx->eflags);
+        if (IS_WORD_CONTEXT(context))
+            return dfa->init_state_word;
+        else if (IS_ORDINARY_CONTEXT(context))
+            return dfa->init_state;
+        else if (IS_BEGBUF_CONTEXT(context) && IS_NEWLINE_CONTEXT(context))
+            return dfa->init_state_begbuf;
+        else if (IS_NEWLINE_CONTEXT(context))
+            return dfa->init_state_nl;
+        else if (IS_BEGBUF_CONTEXT(context)) {
+            /* It is relatively rare case, then calculate on demand.  */
+            return re_acquire_state_context(err, dfa,
+                                            dfa->init_state->entrance_nodes,
+                                            context);
+        } else
+            /* Must not happen?  */
+            return dfa->init_state;
+    } else
+        return dfa->init_state;
+}
+
+/* Check whether the node accepts the byte which is IDX-th
+   byte of the INPUT.  */
+
+static bool
+check_node_accept(const re_match_context_t *mctx, const re_token_t *node,
+                  Idx idx) {
+    unsigned char ch;
+    ch = re_string_byte_at(&mctx->input, idx);
+    switch (node->type) {
+        case CHARACTER:
+            if (node->opr.c != ch)
+                return false;
+            break;
+
+        case SIMPLE_BRACKET:
+            if (!bitset_contain(node->opr.sbcset, ch))
+                return false;
+            break;
+
+        case OP_PERIOD:
+            if ((ch == '\n' && !(mctx->dfa->syntax & RE_DOT_NEWLINE))
+                || (ch == '\0' && (mctx->dfa->syntax & RE_DOT_NOT_NULL)))
+                return false;
+            break;
+
+        default:
+            return false;
+    }
+
+    if (node->constraint) {
+        /* The node has constraints.  Check whether the current context
+       satisfies the constraints.  */
+        unsigned int context = re_string_context_at(&mctx->input, idx,
+                                                    mctx->eflags);
+        if (NOT_SATISFY_NEXT_CONSTRAINT(node->constraint, context))
+            return false;
+    }
+
+    return true;
+}
+
+
+/* Extend the buffers, if the buffers have run out.  */
+
+static reg_errcode_t
+extend_buffers(re_match_context_t
+               *mctx,
+               int min_len
+) {
+    reg_errcode_t ret;
+    re_string_t *pstr = &mctx->input;
+
+/* Avoid overflow.  */
+    if (
+            (MIN (IDX_MAX, SIZE_MAX / sizeof(re_dfastate_t * )) / 2
+             <= pstr->bufs_len))
+        return
+                REG_ESPACE;
+
+/* Double the lengths of the buffers, but allocate at least MIN_LEN.  */
+    ret = re_string_realloc_buffers(pstr,
+                                    MAX (min_len,
+                                         MIN(pstr->len, pstr->bufs_len * 2)));
+    if (
+            (ret
+             != REG_NOERROR))
+        return
+                ret;
+
+    if (mctx->state_log != NULL) {
+/* And double the length of state_log.  */
+/* XXX We have no indication of the size of this buffer.  If this
+allocation fail we have no indication that the state_log array
+does not have the right size.  */
+        re_dfastate_t **new_array = re_realloc(mctx->state_log, re_dfastate_t * ,
+                                               pstr->bufs_len + 1);
+        if (
+                (new_array
+                 == NULL))
+            return
+                    REG_ESPACE;
+        mctx->
+                state_log = new_array;
+    }
+
+/* Then reconstruct the buffers.  */
+    if (pstr->icase) {
+        build_upper_buffer(pstr);
+    } else {
+        {
+            if (pstr->trans != NULL)
+                re_string_translate_buffer(pstr);
+        }
+    }
+    return
+            REG_NOERROR;
+}
+
+/* Functions for state transition.  */
+
+/* Helper functions for transit_state.  */
+
+/* Return the first entry with the same str_idx, or -1 if none is
+   found.  Note that MCTX->BKREF_ENTS is already sorted by MCTX->STR_IDX.  */
+
+static Idx
+search_cur_bkref_entry (const re_match_context_t *mctx, Idx str_idx)
+{
+    Idx left, right, mid, last;
+    last = right = mctx->nbkref_ents;
+    for (left = 0; left < right;)
+    {
+        mid = (left + right) / 2;
+        if (mctx->bkref_ents[mid].str_idx < str_idx)
+            left = mid + 1;
+        else
+            right = mid;
+    }
+    if (left < last && mctx->bkref_ents[left].str_idx == str_idx)
+        return left;
+    else
+        return -1;
+}
+
+/* Register the node NODE, whose type is OP_OPEN_SUBEXP, and which matches
+   at STR_IDX.  */
+
+static reg_errcode_t
+match_ctx_add_subtop(re_match_context_t *mctx, Idx node, Idx str_idx) {
+    if ((mctx->nsub_tops == mctx->asub_tops)) {
+        Idx new_asub_tops = mctx->asub_tops * 2;
+        re_sub_match_top_t **new_array = re_realloc(mctx->sub_tops,
+                                                    re_sub_match_top_t * ,
+                                                    new_asub_tops);
+        if ((new_array == NULL))
+            return REG_ESPACE;
+        mctx->sub_tops = new_array;
+        mctx->asub_tops = new_asub_tops;
+    }
+    mctx->sub_tops[mctx->nsub_tops] = calloc(1, sizeof(re_sub_match_top_t));
+    if ((mctx->sub_tops[mctx->nsub_tops] == NULL))
+        return REG_ESPACE;
+    mctx->sub_tops[mctx->nsub_tops]->node = node;
+    mctx->sub_tops[mctx->nsub_tops++]->str_idx = str_idx;
+    return REG_NOERROR;
+}
+
+/* Register the node NODE, whose type is OP_CLOSE_SUBEXP, and which matches
+   at STR_IDX, whose corresponding OP_OPEN_SUBEXP is SUB_TOP.  */
+
+static re_sub_match_last_t *
+match_ctx_add_sublast (re_sub_match_top_t *subtop, Idx node, Idx str_idx)
+{
+    re_sub_match_last_t *new_entry;
+    if ( (subtop->nlasts == subtop->alasts))
+    {
+        Idx new_alasts = 2 * subtop->alasts + 1;
+        re_sub_match_last_t **new_array = re_realloc (subtop->lasts,
+                                                      re_sub_match_last_t *,
+                                                      new_alasts);
+        if ( (new_array == NULL))
+            return NULL;
+        subtop->lasts = new_array;
+        subtop->alasts = new_alasts;
+    }
+    new_entry = calloc (1, sizeof (re_sub_match_last_t));
+    if ( (new_entry != NULL))
+    {
+        subtop->lasts[subtop->nlasts] = new_entry;
+        new_entry->node = node;
+        new_entry->str_idx = str_idx;
+        ++subtop->nlasts;
+    }
+    return new_entry;
+}
+
+
+/* From the node set CUR_NODES, pick up the nodes whose types are
+   OP_OPEN_SUBEXP and which have corresponding back references in the regular
+   expression. And register them to use them later for evaluating the
+   corresponding back references.  */
+
+static reg_errcode_t
+check_subexp_matching_top(re_match_context_t *mctx, re_node_set *cur_nodes,
+                          Idx str_idx) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    Idx node_idx;
+    reg_errcode_t err;
+
+    /* TODO: This isn't efficient.
+         Because there might be more than one nodes whose types are
+         OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+         nodes.
+         E.g. RE: (a){2}  */
+    for (node_idx = 0; node_idx < cur_nodes->nelem; ++node_idx) {
+        Idx node = cur_nodes->elems[node_idx];
+        if (dfa->nodes[node].type == OP_OPEN_SUBEXP
+            && dfa->nodes[node].opr.idx < BITSET_WORD_BITS
+            && (dfa->used_bkref_map
+                & ((bitset_word_t) 1 << dfa->nodes[node].opr.idx))) {
+            err = match_ctx_add_subtop(mctx, node, str_idx);
+            if ((err != REG_NOERROR))
+                return err;
+        }
+    }
+    return REG_NOERROR;
+}
+
+/* Compute the next node to which "NFA" transit from NODE("NFA" is a NFA
+   corresponding to the DFA).
+   Return the destination node, and update EPS_VIA_NODES;
+   return -1 in case of errors.  */
+
+static Idx
+proceed_next_node (const re_match_context_t *mctx, Idx nregs, regmatch_t *regs,
+                   Idx *pidx, Idx node, re_node_set *eps_via_nodes,
+                   struct re_fail_stack_t *fs)
+{
+    const re_dfa_t *const dfa = mctx->dfa;
+    Idx i;
+    bool ok;
+    if (IS_EPSILON_NODE (dfa->nodes[node].type))
+    {
+        re_node_set *cur_nodes = &mctx->state_log[*pidx]->nodes;
+        re_node_set *edests = &dfa->edests[node];
+        Idx dest_node;
+        ok = re_node_set_insert (eps_via_nodes, node);
+        if ( (! ok))
+            return -2;
+        /* Pick up a valid destination, or return -1 if none
+       is found.  */
+        for (dest_node = -1, i = 0; i < edests->nelem; ++i)
+        {
+            Idx candidate = edests->elems[i];
+            if (!re_node_set_contains (cur_nodes, candidate))
+                continue;
+            if (dest_node == -1)
+                dest_node = candidate;
+
+            else
+            {
+                /* In order to avoid infinite loop like "(a*)*", return the second
+               epsilon-transition if the first was already considered.  */
+                if (re_node_set_contains (eps_via_nodes, dest_node))
+                    return candidate;
+
+                    /* Otherwise, push the second epsilon-transition on the fail stack.  */
+                else if (fs != NULL
+                         && push_fail_stack (fs, *pidx, candidate, nregs, regs,
+                                             eps_via_nodes))
+                    return -2;
+
+                /* We know we are going to exit.  */
+                break;
+            }
+        }
+        return dest_node;
+    }
+    else
+    {
+        Idx naccepted = 0;
+        re_token_type_t type = dfa->nodes[node].type;
+
+        if (type == OP_BACK_REF)
+        {
+            Idx subexp_idx = dfa->nodes[node].opr.idx + 1;
+            naccepted = regs[subexp_idx].rm_eo - regs[subexp_idx].rm_so;
+            if (fs != NULL)
+            {
+                if (regs[subexp_idx].rm_so == -1 || regs[subexp_idx].rm_eo == -1)
+                    return -1;
+                else if (naccepted)
+                {
+                    char *buf = (char *) re_string_get_buffer (&mctx->input);
+                    if (memcmp (buf + regs[subexp_idx].rm_so, buf + *pidx,
+                                naccepted) != 0)
+                        return -1;
+                }
+            }
+
+            if (naccepted == 0)
+            {
+                Idx dest_node;
+                ok = re_node_set_insert (eps_via_nodes, node);
+                if ( (! ok))
+                    return -2;
+                dest_node = dfa->edests[node].elems[0];
+                if (re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+                                          dest_node))
+                    return dest_node;
+            }
+        }
+
+        if (naccepted != 0
+            || check_node_accept (mctx, dfa->nodes + node, *pidx))
+        {
+            Idx dest_node = dfa->nexts[node];
+            *pidx = (naccepted == 0) ? *pidx + 1 : *pidx + naccepted;
+            if (fs && (*pidx > mctx->match_last || mctx->state_log[*pidx] == NULL
+                       || !re_node_set_contains (&mctx->state_log[*pidx]->nodes,
+                                                 dest_node)))
+                return -1;
+            re_node_set_empty (eps_via_nodes);
+            return dest_node;
+        }
+    }
+    return -1;
+}
+
+static reg_errcode_t
+
+push_fail_stack (struct re_fail_stack_t *fs, Idx str_idx, Idx dest_node,
+                 Idx nregs, regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+    reg_errcode_t err;
+    Idx num = fs->num++;
+    if (fs->num == fs->alloc)
+    {
+        struct re_fail_stack_ent_t *new_array;
+        new_array = re_realloc (fs->stack, struct re_fail_stack_ent_t,
+        fs->alloc * 2);
+        if (new_array == NULL)
+            return REG_ESPACE;
+        fs->alloc *= 2;
+        fs->stack = new_array;
+    }
+    fs->stack[num].idx = str_idx;
+    fs->stack[num].node = dest_node;
+    fs->stack[num].regs = re_malloc (regmatch_t, nregs);
+    if (fs->stack[num].regs == NULL)
+        return REG_ESPACE;
+    memcpy (fs->stack[num].regs, regs, sizeof (regmatch_t) * nregs);
+    err = re_node_set_init_copy (&fs->stack[num].eps_via_nodes, eps_via_nodes);
+    return err;
+}
+
+static Idx
+pop_fail_stack (struct re_fail_stack_t *fs, Idx *pidx, Idx nregs,
+                regmatch_t *regs, re_node_set *eps_via_nodes)
+{
+    Idx num = --fs->num;
+    assert (num >= 0);
+    *pidx = fs->stack[num].idx;
+    memcpy (regs, fs->stack[num].regs, sizeof (regmatch_t) * nregs);
+    re_node_set_free (eps_via_nodes);
+    re_free (fs->stack[num].regs);
+    *eps_via_nodes = fs->stack[num].eps_via_nodes;
+    return fs->stack[num].node;
+}
+
+/* Set the positions where the subexpressions are starts/ends to registers
+   PMATCH.
+   Note: We assume that pmatch[0] is already set, and
+   pmatch[i].rm_so == pmatch[i].rm_eo == -1 for 0 < i < nmatch.  */
+
+static reg_errcode_t
+
+set_regs (const regex_t *preg, const re_match_context_t *mctx, size_t nmatch,
+          regmatch_t *pmatch, bool fl_backtrack)
+{
+    const re_dfa_t *dfa = preg->buffer;
+    Idx idx, cur_node;
+    re_node_set eps_via_nodes;
+    struct re_fail_stack_t *fs;
+    struct re_fail_stack_t fs_body = { 0, 2, NULL };
+    regmatch_t *prev_idx_match;
+    bool prev_idx_match_malloced = false;
+    if (fl_backtrack)
+    {
+        fs = &fs_body;
+        fs->stack = re_malloc (struct re_fail_stack_ent_t, fs->alloc);
+        if (fs->stack == NULL)
+            return REG_ESPACE;
+    }
+    else
+        fs = NULL;
+
+    cur_node = dfa->init_node;
+    re_node_set_init_empty (&eps_via_nodes);
+
+    if (__libc_use_alloca (nmatch * sizeof (regmatch_t)))
+        prev_idx_match = (regmatch_t *) alloca (nmatch * sizeof (regmatch_t));
+    else
+    {
+        prev_idx_match = re_malloc (regmatch_t, nmatch);
+        if (prev_idx_match == NULL)
+        {
+            free_fail_stack_return (fs);
+            return REG_ESPACE;
+        }
+        prev_idx_match_malloced = true;
+    }
+    memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+
+    for (idx = pmatch[0].rm_so; idx <= pmatch[0].rm_eo ;)
+    {
+        update_regs (dfa, pmatch, prev_idx_match, cur_node, idx, nmatch);
+
+        if (idx == pmatch[0].rm_eo && cur_node == mctx->last_node)
+        {
+            Idx reg_idx;
+            if (fs)
+            {
+                for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+                    if (pmatch[reg_idx].rm_so > -1 && pmatch[reg_idx].rm_eo == -1)
+                        break;
+                if (reg_idx == nmatch)
+                {
+                    re_node_set_free (&eps_via_nodes);
+                    if (prev_idx_match_malloced)
+                        re_free (prev_idx_match);
+                    return free_fail_stack_return (fs);
+                }
+                cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+                                           &eps_via_nodes);
+            }
+            else
+            {
+                re_node_set_free (&eps_via_nodes);
+                if (prev_idx_match_malloced)
+                    re_free (prev_idx_match);
+                return REG_NOERROR;
+            }
+        }
+
+        /* Proceed to next node.  */
+        cur_node = proceed_next_node (mctx, nmatch, pmatch, &idx, cur_node,
+                                      &eps_via_nodes, fs);
+
+        if ( (cur_node < 0))
+        {
+            if ( (cur_node == -2))
+            {
+                re_node_set_free (&eps_via_nodes);
+                if (prev_idx_match_malloced)
+                    re_free (prev_idx_match);
+                free_fail_stack_return (fs);
+                return REG_ESPACE;
+            }
+            if (fs)
+                cur_node = pop_fail_stack (fs, &idx, nmatch, pmatch,
+                                           &eps_via_nodes);
+            else
+            {
+                re_node_set_free (&eps_via_nodes);
+                if (prev_idx_match_malloced)
+                    re_free (prev_idx_match);
+                return REG_NOMATCH;
+            }
+        }
+    }
+    re_node_set_free (&eps_via_nodes);
+    if (prev_idx_match_malloced)
+        re_free (prev_idx_match);
+    return free_fail_stack_return (fs);
+}
+
+static reg_errcode_t
+free_fail_stack_return (struct re_fail_stack_t *fs)
+{
+    if (fs)
+    {
+        Idx fs_idx;
+        for (fs_idx = 0; fs_idx < fs->num; ++fs_idx)
+        {
+            re_node_set_free (&fs->stack[fs_idx].eps_via_nodes);
+            re_free (fs->stack[fs_idx].regs);
+        }
+        re_free (fs->stack);
+    }
+    return REG_NOERROR;
+}
+
+static void
+update_regs (const re_dfa_t *dfa, regmatch_t *pmatch,
+             regmatch_t *prev_idx_match, Idx cur_node, Idx cur_idx, Idx nmatch)
+{
+    int type = dfa->nodes[cur_node].type;
+    if (type == OP_OPEN_SUBEXP)
+    {
+        Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
+
+        /* We are at the first node of this sub expression.  */
+        if (reg_num < nmatch)
+        {
+            pmatch[reg_num].rm_so = cur_idx;
+            pmatch[reg_num].rm_eo = -1;
+        }
+    }
+    else if (type == OP_CLOSE_SUBEXP)
+    {
+        Idx reg_num = dfa->nodes[cur_node].opr.idx + 1;
+        if (reg_num < nmatch)
+        {
+            /* We are at the last node of this sub expression.  */
+            if (pmatch[reg_num].rm_so < cur_idx)
+            {
+                pmatch[reg_num].rm_eo = cur_idx;
+                /* This is a non-empty match or we are not inside an optional
+               subexpression.  Accept this right away.  */
+                memcpy (prev_idx_match, pmatch, sizeof (regmatch_t) * nmatch);
+            }
+            else
+            {
+                if (dfa->nodes[cur_node].opt_subexp
+                    && prev_idx_match[reg_num].rm_so != -1)
+                    /* We transited through an empty match for an optional
+                       subexpression, like (a?)*, and this is not the subexp's
+                       first match.  Copy back the old content of the registers
+                       so that matches of an inner subexpression are undone as
+                       well, like in ((a?))*.  */
+                    memcpy (pmatch, prev_idx_match, sizeof (regmatch_t) * nmatch);
+                else
+                    /* We completed a subexpression, but it may be part of
+                       an optional one, so do not update PREV_IDX_MATCH.  */
+                    pmatch[reg_num].rm_eo = cur_idx;
+            }
+        }
+    }
+}
+
+/* This function checks the STATE_LOG from the SCTX->last_str_idx to 0
+   and sift the nodes in each states according to the following rules.
+   Updated state_log will be wrote to STATE_LOG.
+
+   Rules: We throw away the Node 'a' in the STATE_LOG[STR_IDX] if...
+     1. When STR_IDX == MATCH_LAST(the last index in the state_log):
+	If 'a' isn't the LAST_NODE and 'a' can't epsilon transit to
+	the LAST_NODE, we throw away the node 'a'.
+     2. When 0 <= STR_IDX < MATCH_LAST and 'a' accepts
+	string 's' and transit to 'b':
+	i. If 'b' isn't in the STATE_LOG[STR_IDX+strlen('s')], we throw
+	   away the node 'a'.
+	ii. If 'b' is in the STATE_LOG[STR_IDX+strlen('s')] but 'b' is
+	    thrown away, we throw away the node 'a'.
+     3. When 0 <= STR_IDX < MATCH_LAST and 'a' epsilon transit to 'b':
+	i. If 'b' isn't in the STATE_LOG[STR_IDX], we throw away the
+	   node 'a'.
+	ii. If 'b' is in the STATE_LOG[STR_IDX] but 'b' is thrown away,
+	    we throw away the node 'a'.  */
+
+#define STATE_NODE_CONTAINS(state,node) \
+  ((state) != NULL && re_node_set_contains (&(state)->nodes, node))
+
+static reg_errcode_t
+sift_states_backward (const re_match_context_t *mctx, re_sift_context_t *sctx)
+{
+    reg_errcode_t err;
+    int null_cnt = 0;
+    Idx str_idx = sctx->last_str_idx;
+    re_node_set cur_dest;
+
+    /* Build sifted state_log[str_idx].  It has the nodes which can epsilon
+       transit to the last_node and the last_node itself.  */
+    err = re_node_set_init_1 (&cur_dest, sctx->last_node);
+    if ( (err != REG_NOERROR))
+        return err;
+    err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+    if ( (err != REG_NOERROR))
+        goto free_return;
+
+    /* Then check each states in the state_log.  */
+    while (str_idx > 0)
+    {
+        /* Update counters.  */
+        null_cnt = (sctx->sifted_states[str_idx] == NULL) ? null_cnt + 1 : 0;
+        if (null_cnt > mctx->max_mb_elem_len)
+        {
+            memset (sctx->sifted_states, '\0',
+                    sizeof (re_dfastate_t *) * str_idx);
+            re_node_set_free (&cur_dest);
+            return REG_NOERROR;
+        }
+        re_node_set_empty (&cur_dest);
+        --str_idx;
+
+        if (mctx->state_log[str_idx])
+        {
+            err = build_sifted_states (mctx, sctx, str_idx, &cur_dest);
+            if ( (err != REG_NOERROR))
+                goto free_return;
+        }
+
+        /* Add all the nodes which satisfy the following conditions:
+       - It can epsilon transit to a node in CUR_DEST.
+       - It is in CUR_SRC.
+       And update state_log.  */
+        err = update_cur_sifted_state (mctx, sctx, str_idx, &cur_dest);
+        if ( (err != REG_NOERROR))
+            goto free_return;
+    }
+    err = REG_NOERROR;
+    free_return:
+    re_node_set_free (&cur_dest);
+    return err;
+}
+
+static reg_errcode_t
+build_sifted_states (const re_match_context_t *mctx, re_sift_context_t *sctx,
+                     Idx str_idx, re_node_set *cur_dest)
+{
+    const re_dfa_t *const dfa = mctx->dfa;
+    const re_node_set *cur_src = &mctx->state_log[str_idx]->non_eps_nodes;
+    Idx i;
+
+    /* Then build the next sifted state.
+       We build the next sifted state on 'cur_dest', and update
+       'sifted_states[str_idx]' with 'cur_dest'.
+       Note:
+       'cur_dest' is the sifted state from 'state_log[str_idx + 1]'.
+       'cur_src' points the node_set of the old 'state_log[str_idx]'
+       (with the epsilon nodes pre-filtered out).  */
+    for (i = 0; i < cur_src->nelem; i++)
+    {
+        Idx prev_node = cur_src->elems[i];
+        int naccepted = 0;
+        bool ok;
+
+        /* We don't check backreferences here.
+       See update_cur_sifted_state().  */
+        if (!naccepted
+            && check_node_accept (mctx, dfa->nodes + prev_node, str_idx)
+            && STATE_NODE_CONTAINS (sctx->sifted_states[str_idx + 1],
+                                    dfa->nexts[prev_node]))
+            naccepted = 1;
+
+        if (naccepted == 0)
+            continue;
+
+        if (sctx->limits.nelem)
+        {
+            Idx to_idx = str_idx + naccepted;
+            if (check_dst_limits (mctx, &sctx->limits,
+                                  dfa->nexts[prev_node], to_idx,
+                                  prev_node, str_idx))
+                continue;
+        }
+        ok = re_node_set_insert (cur_dest, prev_node);
+        if ( (! ok))
+            return REG_ESPACE;
+    }
+
+    return REG_NOERROR;
+}
+
+static reg_errcode_t
+clean_state_log_if_needed (re_match_context_t *mctx, Idx next_state_log_idx)
+{
+    Idx top = mctx->state_log_top;
+
+    if ((next_state_log_idx >= mctx->input.bufs_len
+         && mctx->input.bufs_len < mctx->input.len)
+        || (next_state_log_idx >= mctx->input.valid_len
+            && mctx->input.valid_len < mctx->input.len))
+    {
+        reg_errcode_t err;
+        err = extend_buffers (mctx, next_state_log_idx + 1);
+        if ( (err != REG_NOERROR))
+            return err;
+    }
+
+    if (top < next_state_log_idx)
+    {
+        memset (mctx->state_log + top + 1, '\0',
+                sizeof (re_dfastate_t *) * (next_state_log_idx - top));
+        mctx->state_log_top = next_state_log_idx;
+    }
+    return REG_NOERROR;
+}
+
+/* Enumerate all the candidates which the backreference BKREF_NODE can match
+   at BKREF_STR_IDX, and register them by match_ctx_add_entry().
+   Note that we might collect inappropriate candidates here.
+   However, the cost of checking them strictly here is too high, then we
+   delay these checking for prune_impossible_nodes().  */
+
+static reg_errcode_t
+
+get_subexp(re_match_context_t *mctx, Idx bkref_node, Idx bkref_str_idx) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    Idx subexp_num, sub_top_idx;
+    const char *buf = (const char *) re_string_get_buffer(&mctx->input);
+/* Return if we have already checked BKREF_NODE at BKREF_STR_IDX.  */
+    Idx cache_idx = search_cur_bkref_entry(mctx, bkref_str_idx);
+    if (cache_idx != -1) {
+        const struct re_backref_cache_entry *entry
+                = mctx->bkref_ents + cache_idx;
+        do
+            if (entry->node == bkref_node)
+                return REG_NOERROR; /* We already checked it.  */
+        while (entry++->more);
+    }
+
+    subexp_num = dfa->nodes[bkref_node].opr.idx;
+
+/* For each sub expression  */
+    for (sub_top_idx = 0; sub_top_idx < mctx->nsub_tops; ++sub_top_idx) {
+        reg_errcode_t err;
+        re_sub_match_top_t *sub_top = mctx->sub_tops[sub_top_idx];
+        re_sub_match_last_t *sub_last;
+        Idx sub_last_idx, sl_str, bkref_str_off;
+
+        if (dfa->nodes[sub_top->node].opr.idx != subexp_num)
+            continue; /* It isn't related.  */
+
+        sl_str = sub_top->str_idx;
+        bkref_str_off = bkref_str_idx;
+/* At first, check the last node of sub expressions we already
+evaluated.  */
+        for (sub_last_idx = 0; sub_last_idx < sub_top->nlasts; ++sub_last_idx) {
+            regoff_t sl_str_diff;
+            sub_last = sub_top->lasts[sub_last_idx];
+            sl_str_diff = sub_last->str_idx - sl_str;
+/* The matched string by the sub expression match with the substring
+   at the back reference?  */
+            if (sl_str_diff > 0) {
+                if ((bkref_str_off + sl_str_diff
+                     > mctx->input.valid_len)) {
+/* Not enough chars for a successful match.  */
+                    if (bkref_str_off + sl_str_diff > mctx->input.len)
+                        break;
+
+                    err = clean_state_log_if_needed(mctx,
+                                                    bkref_str_off
+                                                    + sl_str_diff);
+                    if ((err != REG_NOERROR))
+                        return err;
+                    buf = (const char *) re_string_get_buffer(&mctx->input);
+                }
+                if (memcmp(buf + bkref_str_off, buf + sl_str, sl_str_diff) != 0)
+/* We don't need to search this sub expression any more.  */
+                    break;
+            }
+            bkref_str_off += sl_str_diff;
+            sl_str += sl_str_diff;
+            err = get_subexp_sub(mctx, sub_top, sub_last, bkref_node,
+                                 bkref_str_idx);
+
+/* Reload buf, since the preceding call might have reallocated
+   the buffer.  */
+            buf = (const char *) re_string_get_buffer(&mctx->input);
+
+            if (err == REG_NOMATCH)
+                continue;
+            if ((err != REG_NOERROR))
+                return err;
+        }
+
+        if (sub_last_idx < sub_top->nlasts)
+            continue;
+        if (sub_last_idx > 0)
+            ++sl_str;
+/* Then, search for the other last nodes of the sub expression.  */
+        for (; sl_str <= bkref_str_idx; ++sl_str) {
+            Idx cls_node;
+            regoff_t sl_str_off;
+            const re_node_set *nodes;
+            sl_str_off = sl_str - sub_top->str_idx;
+/* The matched string by the sub expression match with the substring
+   at the back reference?  */
+            if (sl_str_off > 0) {
+                if ((bkref_str_off >= mctx->input.valid_len)) {
+/* If we are at the end of the input, we cannot match.  */
+                    if (bkref_str_off >= mctx->input.len)
+                        break;
+
+                    err = extend_buffers(mctx, bkref_str_off + 1);
+                    if ((err != REG_NOERROR))
+                        return err;
+
+                    buf = (const char *) re_string_get_buffer(&mctx->input);
+                }
+                if (buf[bkref_str_off++] != buf[sl_str - 1])
+                    break; /* We don't need to search this sub expression
+			  any more.  */
+            }
+            if (mctx->state_log[sl_str] == NULL)
+                continue;
+/* Does this state have a ')' of the sub expression?  */
+            nodes = &mctx->state_log[sl_str]->nodes;
+            cls_node = find_subexp_node(dfa, nodes, subexp_num,
+                                        OP_CLOSE_SUBEXP);
+            if (cls_node == -1)
+                continue; /* No.  */
+            if (sub_top->path == NULL) {
+                sub_top->path = calloc(sizeof(state_array_t),
+                                       sl_str - sub_top->str_idx + 1);
+                if (sub_top->path == NULL)
+                    return REG_ESPACE;
+            }
+/* Can the OP_OPEN_SUBEXP node arrive the OP_CLOSE_SUBEXP node
+   in the current context?  */
+            err = check_arrival(mctx, sub_top->path, sub_top->node,
+                                sub_top->str_idx, cls_node, sl_str,
+                                OP_CLOSE_SUBEXP);
+            if (err == REG_NOMATCH)
+                continue;
+            if ((err != REG_NOERROR))
+                return err;
+            sub_last = match_ctx_add_sublast(sub_top, cls_node, sl_str);
+            if ((sub_last == NULL))
+                return REG_ESPACE;
+            err = get_subexp_sub(mctx, sub_top, sub_last, bkref_node,
+                                 bkref_str_idx);
+            if (err == REG_NOMATCH)
+                continue;
+        }
+    }
+    return REG_NOERROR;
+}
+
+/* Helper functions for get_subexp().  */
+
+/* Check SUB_LAST can arrive to the back reference BKREF_NODE at BKREF_STR.
+   If it can arrive, register the sub expression expressed with SUB_TOP
+   and SUB_LAST.  */
+
+static reg_errcode_t
+get_subexp_sub(re_match_context_t *mctx, const re_sub_match_top_t *sub_top,
+               re_sub_match_last_t *sub_last, Idx bkref_node, Idx bkref_str) {
+    reg_errcode_t err;
+    Idx to_idx;
+    /* Can the subexpression arrive the back reference?  */
+    err = check_arrival(mctx, &sub_last->path, sub_last->node,
+                        sub_last->str_idx, bkref_node, bkref_str,
+                        OP_OPEN_SUBEXP);
+    if (err != REG_NOERROR)
+        return err;
+    err = match_ctx_add_entry(mctx, bkref_node, bkref_str, sub_top->str_idx,
+                              sub_last->str_idx);
+    if ((err != REG_NOERROR))
+        return err;
+    to_idx = bkref_str + sub_last->str_idx - sub_top->str_idx;
+    return clean_state_log_if_needed(mctx, to_idx);
+}
+
+/* Find the first node which is '(' or ')' and whose index is SUBEXP_IDX.
+   Search '(' if FL_OPEN, or search ')' otherwise.
+   TODO: This function isn't efficient...
+	 Because there might be more than one nodes whose types are
+	 OP_OPEN_SUBEXP and whose index is SUBEXP_IDX, we must check all
+	 nodes.
+	 E.g. RE: (a){2}  */
+
+static Idx
+find_subexp_node(const re_dfa_t *dfa, const re_node_set *nodes,
+                 Idx subexp_idx, int type) {
+    Idx cls_idx;
+    for (cls_idx = 0; cls_idx < nodes->nelem; ++cls_idx) {
+        Idx cls_node = nodes->elems[cls_idx];
+        const re_token_t *node = dfa->nodes + cls_node;
+        if (node->type == type
+            && node->opr.idx == subexp_idx)
+            return cls_node;
+    }
+    return -1;
+}
+
+/* Check whether the node TOP_NODE at TOP_STR can arrive to the node
+   LAST_NODE at LAST_STR.  We record the path onto PATH since it will be
+   heavily reused.
+   Return REG_NOERROR if it can arrive, or REG_NOMATCH otherwise.  */
+
+static reg_errcode_t
+
+check_arrival(re_match_context_t *mctx, state_array_t *path, Idx top_node,
+              Idx top_str, Idx last_node, Idx last_str, int type) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    reg_errcode_t err = REG_NOERROR;
+    Idx subexp_num, backup_cur_idx, str_idx, null_cnt;
+    re_dfastate_t *cur_state = NULL;
+    re_node_set *cur_nodes, next_nodes;
+    re_dfastate_t **backup_state_log;
+    unsigned int context;
+
+    subexp_num = dfa->nodes[top_node].opr.idx;
+/* Extend the buffer if we need.  */
+    if ((path->alloc < last_str + mctx->max_mb_elem_len + 1)) {
+        re_dfastate_t **new_array;
+        Idx old_alloc = path->alloc;
+        Idx incr_alloc = last_str + mctx->max_mb_elem_len + 1;
+        Idx new_alloc;
+        if ((IDX_MAX - old_alloc < incr_alloc))
+            return REG_ESPACE;
+        new_alloc = old_alloc + incr_alloc;
+        if ((SIZE_MAX / sizeof(re_dfastate_t * ) < new_alloc))
+            return REG_ESPACE;
+        new_array = re_realloc(path->array, re_dfastate_t * , new_alloc);
+        if ((new_array == NULL))
+            return REG_ESPACE;
+        path->array = new_array;
+        path->alloc = new_alloc;
+        memset(new_array + old_alloc, '\0',
+               sizeof(re_dfastate_t * ) * (path->alloc - old_alloc));
+    }
+
+    str_idx = path->next_idx ? path->next_idx : top_str;
+
+/* Temporary modify MCTX.  */
+    backup_state_log = mctx->state_log;
+    backup_cur_idx = mctx->input.cur_idx;
+    mctx->state_log = path->array;
+    mctx->input.cur_idx = str_idx;
+
+/* Setup initial node set.  */
+    context = re_string_context_at(&mctx->input, str_idx - 1, mctx->eflags);
+    if (str_idx == top_str) {
+        err = re_node_set_init_1(&next_nodes, top_node);
+        if ((err != REG_NOERROR))
+            return err;
+        err = check_arrival_expand_ecl(dfa, &next_nodes, subexp_num, type);
+        if ((err != REG_NOERROR)) {
+            re_node_set_free(&next_nodes);
+            return err;
+        }
+    } else {
+        cur_state = mctx->state_log[str_idx];
+        if (cur_state && cur_state->has_backref) {
+            err = re_node_set_init_copy(&next_nodes, &cur_state->nodes);
+            if ((err != REG_NOERROR))
+                return err;
+        } else
+            re_node_set_init_empty(&next_nodes);
+    }
+    if (str_idx == top_str || (cur_state && cur_state->has_backref)) {
+        if (next_nodes.nelem) {
+            err = expand_bkref_cache(mctx, &next_nodes, str_idx,
+                                     subexp_num, type);
+            if ((err != REG_NOERROR)) {
+                re_node_set_free(&next_nodes);
+                return err;
+            }
+        }
+        cur_state = re_acquire_state_context(&err, dfa, &next_nodes, context);
+        if ((cur_state == NULL && err != REG_NOERROR)) {
+            re_node_set_free(&next_nodes);
+            return err;
+        }
+        mctx->state_log[str_idx] = cur_state;
+    }
+
+    for (null_cnt = 0; str_idx < last_str && null_cnt <= mctx->max_mb_elem_len;) {
+        re_node_set_empty(&next_nodes);
+        if (mctx->state_log[str_idx + 1]) {
+            err = re_node_set_merge(&next_nodes,
+                                    &mctx->state_log[str_idx + 1]->nodes);
+            if ((err != REG_NOERROR)) {
+                re_node_set_free(&next_nodes);
+                return err;
+            }
+        }
+        if (cur_state) {
+            err = check_arrival_add_next_nodes(mctx, str_idx,
+                                               &cur_state->non_eps_nodes,
+                                               &next_nodes);
+            if ((err != REG_NOERROR)) {
+                re_node_set_free(&next_nodes);
+                return err;
+            }
+        }
+        ++str_idx;
+        if (next_nodes.nelem) {
+            err = check_arrival_expand_ecl(dfa, &next_nodes, subexp_num, type);
+            if ((err != REG_NOERROR)) {
+                re_node_set_free(&next_nodes);
+                return err;
+            }
+            err = expand_bkref_cache(mctx, &next_nodes, str_idx,
+                                     subexp_num, type);
+            if ((err != REG_NOERROR)) {
+                re_node_set_free(&next_nodes);
+                return err;
+            }
+        }
+        context = re_string_context_at(&mctx->input, str_idx - 1, mctx->eflags);
+        cur_state = re_acquire_state_context(&err, dfa, &next_nodes, context);
+        if ((cur_state == NULL && err != REG_NOERROR)) {
+            re_node_set_free(&next_nodes);
+            return err;
+        }
+        mctx->state_log[str_idx] = cur_state;
+        null_cnt = cur_state == NULL ? null_cnt + 1 : 0;
+    }
+    re_node_set_free(&next_nodes);
+    cur_nodes = (mctx->state_log[last_str] == NULL ? NULL
+                                                   : &mctx->state_log[last_str]->nodes);
+    path->next_idx = str_idx;
+
+/* Fix MCTX.  */
+    mctx->state_log = backup_state_log;
+    mctx->input.cur_idx = backup_cur_idx;
+
+/* Then check the current node set has the node LAST_NODE.  */
+    if (cur_nodes != NULL && re_node_set_contains(cur_nodes, last_node))
+        return REG_NOERROR;
+
+    return REG_NOMATCH;
+}
+
+/* Helper functions for check_arrival.  */
+
+/* Calculate the destination nodes of CUR_NODES at STR_IDX, and append them
+   to NEXT_NODES.
+   TODO: This function is similar to the functions transit_state*(),
+	 however this function has many additional works.
+	 Can't we unify them?  */
+
+static reg_errcode_t
+
+check_arrival_add_next_nodes(re_match_context_t *mctx, Idx str_idx,
+                             re_node_set *cur_nodes, re_node_set *next_nodes) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    bool ok;
+    Idx cur_idx;
+    re_node_set union_set;
+    re_node_set_init_empty(&union_set);
+    for (cur_idx = 0; cur_idx < cur_nodes->nelem; ++cur_idx) {
+        int naccepted = 0;
+        Idx cur_node = cur_nodes->elems[cur_idx];
+        if (naccepted
+            || check_node_accept(mctx, dfa->nodes + cur_node, str_idx)) {
+            ok = re_node_set_insert(next_nodes, dfa->nexts[cur_node]);
+            if ((!ok)) {
+                re_node_set_free(&union_set);
+                return REG_ESPACE;
+            }
+        }
+    }
+    re_node_set_free(&union_set);
+    return REG_NOERROR;
+}
+
+/* For all the nodes in CUR_NODES, add the epsilon closures of them to
+   CUR_NODES, however exclude the nodes which are:
+    - inside the sub expression whose number is EX_SUBEXP, if FL_OPEN.
+    - out of the sub expression whose number is EX_SUBEXP, if !FL_OPEN.
+*/
+
+static reg_errcode_t
+check_arrival_expand_ecl(const re_dfa_t *dfa, re_node_set *cur_nodes,
+                         Idx ex_subexp, int type) {
+    reg_errcode_t err;
+    Idx idx, outside_node;
+    re_node_set new_nodes;
+    err = re_node_set_alloc(&new_nodes, cur_nodes->nelem);
+    if ((err != REG_NOERROR))
+        return err;
+    /* Create a new node set NEW_NODES with the nodes which are epsilon
+       closures of the node in CUR_NODES.  */
+
+    for (idx = 0; idx < cur_nodes->nelem; ++idx) {
+        Idx cur_node = cur_nodes->elems[idx];
+        const re_node_set *eclosure = dfa->eclosures + cur_node;
+        outside_node = find_subexp_node(dfa, eclosure, ex_subexp, type);
+        if (outside_node == -1) {
+            /* There are no problematic nodes, just merge them.  */
+            err = re_node_set_merge(&new_nodes, eclosure);
+            if ((err != REG_NOERROR)) {
+                re_node_set_free(&new_nodes);
+                return err;
+            }
+        } else {
+            /* There are problematic nodes, re-calculate incrementally.  */
+            err = check_arrival_expand_ecl_sub(dfa, &new_nodes, cur_node,
+                                               ex_subexp, type);
+            if ((err != REG_NOERROR)) {
+                re_node_set_free(&new_nodes);
+                return err;
+            }
+        }
+    }
+    re_node_set_free(cur_nodes);
+    *cur_nodes = new_nodes;
+    return REG_NOERROR;
+}
+
+/* Helper function for check_arrival_expand_ecl.
+   Check incrementally the epsilon closure of TARGET, and if it isn't
+   problematic append it to DST_NODES.  */
+
+static reg_errcode_t
+
+check_arrival_expand_ecl_sub(const re_dfa_t *dfa, re_node_set *dst_nodes,
+                             Idx target, Idx ex_subexp, int type) {
+    Idx cur_node;
+    for (cur_node = target; !re_node_set_contains(dst_nodes, cur_node);) {
+        bool ok;
+
+        if (dfa->nodes[cur_node].type == type
+            && dfa->nodes[cur_node].opr.idx == ex_subexp) {
+            if (type == OP_CLOSE_SUBEXP) {
+                ok = re_node_set_insert(dst_nodes, cur_node);
+                if ((!ok))
+                    return REG_ESPACE;
+            }
+            break;
+        }
+        ok = re_node_set_insert(dst_nodes, cur_node);
+        if ((!ok))
+            return REG_ESPACE;
+        if (dfa->edests[cur_node].nelem == 0)
+            break;
+        if (dfa->edests[cur_node].nelem == 2) {
+            reg_errcode_t err;
+            err = check_arrival_expand_ecl_sub(dfa, dst_nodes,
+                                               dfa->edests[cur_node].elems[1],
+                                               ex_subexp, type);
+            if ((err != REG_NOERROR))
+                return err;
+        }
+        cur_node = dfa->edests[cur_node].elems[0];
+    }
+    return REG_NOERROR;
+}
+
+/* For all the back references in the current state, calculate the
+   destination of the back references by the appropriate entry
+   in MCTX->BKREF_ENTS.  */
+
+static reg_errcode_t
+expand_bkref_cache(re_match_context_t *mctx, re_node_set *cur_nodes,
+                   Idx cur_str, Idx subexp_num, int type) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    reg_errcode_t err;
+    Idx cache_idx_start = search_cur_bkref_entry(mctx, cur_str);
+    struct re_backref_cache_entry *ent;
+
+    if (cache_idx_start == -1)
+        return REG_NOERROR;
+
+    restart:
+    ent = mctx->bkref_ents + cache_idx_start;
+    do {
+        Idx to_idx, next_node;
+
+/* Is this entry ENT is appropriate?  */
+        if (!re_node_set_contains(cur_nodes, ent->node))
+            continue; /* No.  */
+
+        to_idx = cur_str + ent->subexp_to - ent->subexp_from;
+/* Calculate the destination of the back reference, and append it
+to MCTX->STATE_LOG.  */
+        if (to_idx == cur_str) {
+/* The backreference did epsilon transit, we must re-check all the
+   node in the current state.  */
+            re_node_set new_dests;
+            reg_errcode_t err2, err3;
+            next_node = dfa->edests[ent->node].elems[0];
+            if (re_node_set_contains(cur_nodes, next_node))
+                continue;
+            err = re_node_set_init_1(&new_dests, next_node);
+            err2 = check_arrival_expand_ecl(dfa, &new_dests, subexp_num, type);
+            err3 = re_node_set_merge(cur_nodes, &new_dests);
+            re_node_set_free(&new_dests);
+            if ((err != REG_NOERROR || err2 != REG_NOERROR
+                 || err3 != REG_NOERROR)) {
+                err = (err != REG_NOERROR ? err
+                                          : (err2 != REG_NOERROR ? err2 : err3));
+                return err;
+            }
+/* TODO: It is still inefficient...  */
+            goto restart;
+        } else {
+            re_node_set union_set;
+            next_node = dfa->nexts[ent->node];
+            if (mctx->state_log[to_idx]) {
+                bool ok;
+                if (re_node_set_contains(&mctx->state_log[to_idx]->nodes,
+                                         next_node))
+                    continue;
+                err = re_node_set_init_copy(&union_set,
+                                            &mctx->state_log[to_idx]->nodes);
+                ok = re_node_set_insert(&union_set, next_node);
+                if ((err != REG_NOERROR || !ok)) {
+                    re_node_set_free(&union_set);
+                    err = err != REG_NOERROR ? err : REG_ESPACE;
+                    return err;
+                }
+            } else {
+                err = re_node_set_init_1(&union_set, next_node);
+                if ((err != REG_NOERROR))
+                    return err;
+            }
+            mctx->state_log[to_idx] = re_acquire_state(&err, dfa, &union_set);
+            re_node_set_free(&union_set);
+            if ((mctx->state_log[to_idx] == NULL
+                 && err != REG_NOERROR))
+                return err;
+        }
+    } while (ent++->more);
+    return REG_NOERROR;
+}
+
+/* Build transition table for the state.
+   Return true if successful.  */
+
+static bool
+build_trtable (const re_dfa_t *dfa, re_dfastate_t *state)
+{
+    reg_errcode_t err;
+    Idx i, j;
+    int ch;
+    bool need_word_trtable = false;
+    bitset_word_t elem, mask;
+    bool dests_node_malloced = false;
+    bool dest_states_malloced = false;
+    Idx ndests; /* Number of the destination states from 'state'.  */
+    re_dfastate_t **trtable;
+    re_dfastate_t **dest_states = NULL, **dest_states_word, **dest_states_nl;
+    re_node_set follows, *dests_node;
+    bitset_t *dests_ch;
+    bitset_t acceptable;
+
+    struct dests_alloc
+    {
+        re_node_set dests_node[SBC_MAX];
+        bitset_t dests_ch[SBC_MAX];
+    } *dests_alloc;
+
+    /* We build DFA states which corresponds to the destination nodes
+       from 'state'.  'dests_node[i]' represents the nodes which i-th
+       destination state contains, and 'dests_ch[i]' represents the
+       characters which i-th destination state accepts.  */
+    if (__libc_use_alloca (sizeof (struct dests_alloc)))
+        dests_alloc = (struct dests_alloc *) alloca (sizeof (struct dests_alloc));
+    else
+    {
+        dests_alloc = re_malloc (struct dests_alloc, 1);
+        if ( (dests_alloc == NULL))
+            return false;
+        dests_node_malloced = true;
+    }
+    dests_node = dests_alloc->dests_node;
+    dests_ch = dests_alloc->dests_ch;
+
+    /* Initialize transition table.  */
+    state->word_trtable = state->trtable = NULL;
+
+    /* At first, group all nodes belonging to 'state' into several
+       destinations.  */
+    ndests = group_nodes_into_DFAstates (dfa, state, dests_node, dests_ch);
+    if ( (ndests <= 0))
+    {
+        if (dests_node_malloced)
+            re_free (dests_alloc);
+        /* Return false in case of an error, true otherwise.  */
+        if (ndests == 0)
+        {
+            state->trtable = (re_dfastate_t **)
+                    calloc (sizeof (re_dfastate_t *), SBC_MAX);
+            if ( (state->trtable == NULL))
+                return false;
+            return true;
+        }
+        return false;
+    }
+
+    err = re_node_set_alloc (&follows, ndests + 1);
+    if ( (err != REG_NOERROR))
+        goto out_free;
+
+    /* Avoid arithmetic overflow in size calculation.  */
+    size_t ndests_max
+            = ((SIZE_MAX - (sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX)
+               / (3 * sizeof (re_dfastate_t *)));
+    if ( (ndests_max < ndests))
+        goto out_free;
+
+    if (__libc_use_alloca ((sizeof (re_node_set) + sizeof (bitset_t)) * SBC_MAX
+                           + ndests * 3 * sizeof (re_dfastate_t *)))
+        dest_states = (re_dfastate_t **)
+                alloca (ndests * 3 * sizeof (re_dfastate_t *));
+    else
+    {
+        dest_states = re_malloc (re_dfastate_t *, ndests * 3);
+        if ( (dest_states == NULL))
+        {
+            out_free:
+            if (dest_states_malloced)
+                re_free (dest_states);
+            re_node_set_free (&follows);
+            for (i = 0; i < ndests; ++i)
+                re_node_set_free (dests_node + i);
+            if (dests_node_malloced)
+                re_free (dests_alloc);
+            return false;
+        }
+        dest_states_malloced = true;
+    }
+    dest_states_word = dest_states + ndests;
+    dest_states_nl = dest_states_word + ndests;
+    bitset_empty (acceptable);
+
+    /* Then build the states for all destinations.  */
+    for (i = 0; i < ndests; ++i)
+    {
+        Idx next_node;
+        re_node_set_empty (&follows);
+        /* Merge the follows of this destination states.  */
+        for (j = 0; j < dests_node[i].nelem; ++j)
+        {
+            next_node = dfa->nexts[dests_node[i].elems[j]];
+            if (next_node != -1)
+            {
+                err = re_node_set_merge (&follows, dfa->eclosures + next_node);
+                if ( (err != REG_NOERROR))
+                    goto out_free;
+            }
+        }
+        dest_states[i] = re_acquire_state_context (&err, dfa, &follows, 0);
+        if ( (dest_states[i] == NULL && err != REG_NOERROR))
+            goto out_free;
+        /* If the new state has context constraint,
+       build appropriate states for these contexts.  */
+        if (dest_states[i]->has_constraint)
+        {
+            dest_states_word[i] = re_acquire_state_context (&err, dfa, &follows,
+                                                            CONTEXT_WORD);
+            if ( (dest_states_word[i] == NULL
+                                  && err != REG_NOERROR))
+                goto out_free;
+
+            if (dest_states[i] != dest_states_word[i] && dfa->mb_cur_max > 1)
+                need_word_trtable = true;
+
+            dest_states_nl[i] = re_acquire_state_context (&err, dfa, &follows,
+                                                          CONTEXT_NEWLINE);
+            if ( (dest_states_nl[i] == NULL && err != REG_NOERROR))
+                goto out_free;
+        }
+        else
+        {
+            dest_states_word[i] = dest_states[i];
+            dest_states_nl[i] = dest_states[i];
+        }
+        bitset_merge (acceptable, dests_ch[i]);
+    }
+
+    if (! (need_word_trtable))
+    {
+        /* We don't care about whether the following character is a word
+       character, or we are in a single-byte character set so we can
+       discern by looking at the character code: allocate a
+       256-entry transition table.  */
+        trtable = state->trtable =
+                (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), SBC_MAX);
+        if ( (trtable == NULL))
+            goto out_free;
+
+        /* For all characters ch...:  */
+        for (i = 0; i < BITSET_WORDS; ++i)
+            for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+                 elem;
+                 mask <<= 1, elem >>= 1, ++ch)
+                if ( (elem & 1))
+                {
+                    /* There must be exactly one destination which accepts
+                   character ch.  See group_nodes_into_DFAstates.  */
+                    for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+                        ;
+
+                    /* j-th destination accepts the word character ch.  */
+                    if (dfa->word_char[i] & mask)
+                        trtable[ch] = dest_states_word[j];
+                    else
+                        trtable[ch] = dest_states[j];
+                }
+    }
+    else
+    {
+        /* We care about whether the following character is a word
+       character, and we are in a multi-byte character set: discern
+       by looking at the character code: build two 256-entry
+       transition tables, one starting at trtable[0] and one
+       starting at trtable[SBC_MAX].  */
+        trtable = state->word_trtable =
+                (re_dfastate_t **) calloc (sizeof (re_dfastate_t *), 2 * SBC_MAX);
+        if ( (trtable == NULL))
+            goto out_free;
+
+        /* For all characters ch...:  */
+        for (i = 0; i < BITSET_WORDS; ++i)
+            for (ch = i * BITSET_WORD_BITS, elem = acceptable[i], mask = 1;
+                 elem;
+                 mask <<= 1, elem >>= 1, ++ch)
+                if ( (elem & 1))
+                {
+                    /* There must be exactly one destination which accepts
+                   character ch.  See group_nodes_into_DFAstates.  */
+                    for (j = 0; (dests_ch[j][i] & mask) == 0; ++j)
+                        ;
+
+                    /* j-th destination accepts the word character ch.  */
+                    trtable[ch] = dest_states[j];
+                    trtable[ch + SBC_MAX] = dest_states_word[j];
+                }
+    }
+
+    /* new line */
+    if (bitset_contain (acceptable, NEWLINE_CHAR))
+    {
+        /* The current state accepts newline character.  */
+        for (j = 0; j < ndests; ++j)
+            if (bitset_contain (dests_ch[j], NEWLINE_CHAR))
+            {
+                /* k-th destination accepts newline character.  */
+                trtable[NEWLINE_CHAR] = dest_states_nl[j];
+                if (need_word_trtable)
+                    trtable[NEWLINE_CHAR + SBC_MAX] = dest_states_nl[j];
+                /* There must be only one destination which accepts
+                   newline.  See group_nodes_into_DFAstates.  */
+                break;
+            }
+    }
+
+    if (dest_states_malloced)
+        re_free (dest_states);
+
+    re_node_set_free (&follows);
+    for (i = 0; i < ndests; ++i)
+        re_node_set_free (dests_node + i);
+
+    if (dests_node_malloced)
+        re_free (dests_alloc);
+
+    return true;
+}
+
+/* Group all nodes belonging to STATE into several destinations.
+   Then for all destinations, set the nodes belonging to the destination
+   to DESTS_NODE[i] and set the characters accepted by the destination
+   to DEST_CH[i].  This function return the number of destinations.  */
+
+static Idx
+group_nodes_into_DFAstates (const re_dfa_t *dfa, const re_dfastate_t *state,
+                            re_node_set *dests_node, bitset_t *dests_ch)
+{
+    reg_errcode_t err;
+    bool ok;
+    Idx i, j, k;
+    Idx ndests; /* Number of the destinations from 'state'.  */
+    bitset_t accepts; /* Characters a node can accept.  */
+    const re_node_set *cur_nodes = &state->nodes;
+    bitset_empty (accepts);
+    ndests = 0;
+
+    /* For all the nodes belonging to 'state',  */
+    for (i = 0; i < cur_nodes->nelem; ++i)
+    {
+        re_token_t *node = &dfa->nodes[cur_nodes->elems[i]];
+        re_token_type_t type = node->type;
+        unsigned int constraint = node->constraint;
+
+        /* Enumerate all single byte character this node can accept.  */
+        if (type == CHARACTER)
+            bitset_set (accepts, node->opr.c);
+        else if (type == SIMPLE_BRACKET)
+        {
+            bitset_merge (accepts, node->opr.sbcset);
+        }
+        else if (type == OP_PERIOD)
+        {
+            bitset_set_all (accepts);
+            if (!(dfa->syntax & RE_DOT_NEWLINE))
+                bitset_clear (accepts, '\n');
+            if (dfa->syntax & RE_DOT_NOT_NULL)
+                bitset_clear (accepts, '\0');
+        }
+        else
+            continue;
+
+        /* Check the 'accepts' and sift the characters which are not
+       match it the context.  */
+        if (constraint)
+        {
+            if (constraint & NEXT_NEWLINE_CONSTRAINT)
+            {
+                bool accepts_newline = bitset_contain (accepts, NEWLINE_CHAR);
+                bitset_empty (accepts);
+                if (accepts_newline)
+                    bitset_set (accepts, NEWLINE_CHAR);
+                else
+                    continue;
+            }
+            if (constraint & NEXT_ENDBUF_CONSTRAINT)
+            {
+                bitset_empty (accepts);
+                continue;
+            }
+
+            if (constraint & NEXT_WORD_CONSTRAINT)
+            {
+                bitset_word_t any_set = 0;
+                if (type == CHARACTER && !node->word_char)
+                {
+                    bitset_empty (accepts);
+                    continue;
+                }
+                for (j = 0; j < BITSET_WORDS; ++j)
+                    any_set |= (accepts[j] &= dfa->word_char[j]);
+                if (!any_set)
+                    continue;
+            }
+            if (constraint & NEXT_NOTWORD_CONSTRAINT)
+            {
+                bitset_word_t any_set = 0;
+                if (type == CHARACTER && node->word_char)
+                {
+                    bitset_empty (accepts);
+                    continue;
+                }
+                for (j = 0; j < BITSET_WORDS; ++j)
+                    any_set |= (accepts[j] &= ~dfa->word_char[j]);
+                if (!any_set)
+                    continue;
+            }
+        }
+
+        /* Then divide 'accepts' into DFA states, or create a new
+       state.  Above, we make sure that accepts is not empty.  */
+        for (j = 0; j < ndests; ++j)
+        {
+            bitset_t intersec; /* Intersection sets, see below.  */
+            bitset_t remains;
+            /* Flags, see below.  */
+            bitset_word_t has_intersec, not_subset, not_consumed;
+
+            /* Optimization, skip if this state doesn't accept the character.  */
+            if (type == CHARACTER && !bitset_contain (dests_ch[j], node->opr.c))
+                continue;
+
+            /* Enumerate the intersection set of this state and 'accepts'.  */
+            has_intersec = 0;
+            for (k = 0; k < BITSET_WORDS; ++k)
+                has_intersec |= intersec[k] = accepts[k] & dests_ch[j][k];
+            /* And skip if the intersection set is empty.  */
+            if (!has_intersec)
+                continue;
+
+            /* Then check if this state is a subset of 'accepts'.  */
+            not_subset = not_consumed = 0;
+            for (k = 0; k < BITSET_WORDS; ++k)
+            {
+                not_subset |= remains[k] = ~accepts[k] & dests_ch[j][k];
+                not_consumed |= accepts[k] = accepts[k] & ~dests_ch[j][k];
+            }
+
+            /* If this state isn't a subset of 'accepts', create a
+               new group state, which has the 'remains'. */
+            if (not_subset)
+            {
+                bitset_copy (dests_ch[ndests], remains);
+                bitset_copy (dests_ch[j], intersec);
+                err = re_node_set_init_copy (dests_node + ndests, &dests_node[j]);
+                if ( (err != REG_NOERROR))
+                    goto error_return;
+                ++ndests;
+            }
+
+            /* Put the position in the current group. */
+            ok = re_node_set_insert (&dests_node[j], cur_nodes->elems[i]);
+            if ( (! ok))
+                goto error_return;
+
+            /* If all characters are consumed, go to next node. */
+            if (!not_consumed)
+                break;
+        }
+        /* Some characters remain, create a new group. */
+        if (j == ndests)
+        {
+            bitset_copy (dests_ch[ndests], accepts);
+            err = re_node_set_init_1 (dests_node + ndests, cur_nodes->elems[i]);
+            if ( (err != REG_NOERROR))
+                goto error_return;
+            ++ndests;
+            bitset_empty (accepts);
+        }
+    }
+    return ndests;
+    error_return:
+    for (j = 0; j < ndests; ++j)
+        re_node_set_free (dests_node + j);
+    return -1;
+}
+
+
+static reg_errcode_t
+update_cur_sifted_state (const re_match_context_t *mctx,
+                         re_sift_context_t *sctx, Idx str_idx,
+                         re_node_set *dest_nodes)
+{
+    const re_dfa_t *const dfa = mctx->dfa;
+    reg_errcode_t err = REG_NOERROR;
+    const re_node_set *candidates;
+    candidates = ((mctx->state_log[str_idx] == NULL) ? NULL
+                                                     : &mctx->state_log[str_idx]->nodes);
+
+    if (dest_nodes->nelem == 0)
+        sctx->sifted_states[str_idx] = NULL;
+    else
+    {
+        if (candidates)
+        {
+            /* At first, add the nodes which can epsilon transit to a node in
+               DEST_NODE.  */
+            err = add_epsilon_src_nodes (dfa, dest_nodes, candidates);
+            if ( (err != REG_NOERROR))
+                return err;
+
+            /* Then, check the limitations in the current sift_context.  */
+            if (sctx->limits.nelem)
+            {
+                err = check_subexp_limits (dfa, dest_nodes, candidates, &sctx->limits,
+                                           mctx->bkref_ents, str_idx);
+                if ( (err != REG_NOERROR))
+                    return err;
+            }
+        }
+
+        sctx->sifted_states[str_idx] = re_acquire_state (&err, dfa, dest_nodes);
+        if ( (err != REG_NOERROR))
+            return err;
+    }
+
+    if (candidates && mctx->state_log[str_idx]->has_backref)
+    {
+        err = sift_states_bkref (mctx, sctx, str_idx, candidates);
+        if ( (err != REG_NOERROR))
+            return err;
+    }
+    return REG_NOERROR;
+}
+
+static reg_errcode_t
+
+add_epsilon_src_nodes (const re_dfa_t *dfa, re_node_set *dest_nodes,
+                       const re_node_set *candidates)
+{
+    reg_errcode_t err = REG_NOERROR;
+    Idx i;
+
+    re_dfastate_t *state = re_acquire_state (&err, dfa, dest_nodes);
+    if ( (err != REG_NOERROR))
+        return err;
+
+    if (!state->inveclosure.alloc)
+    {
+        err = re_node_set_alloc (&state->inveclosure, dest_nodes->nelem);
+        if ( (err != REG_NOERROR))
+            return REG_ESPACE;
+        for (i = 0; i < dest_nodes->nelem; i++)
+        {
+            err = re_node_set_merge (&state->inveclosure,
+                                     dfa->inveclosures + dest_nodes->elems[i]);
+            if ( (err != REG_NOERROR))
+                return REG_ESPACE;
+        }
+    }
+    return re_node_set_add_intersect (dest_nodes, candidates,
+                                      &state->inveclosure);
+}
+
+static reg_errcode_t
+sub_epsilon_src_nodes (const re_dfa_t *dfa, Idx node, re_node_set *dest_nodes,
+                       const re_node_set *candidates)
+{
+    Idx ecl_idx;
+    reg_errcode_t err;
+    re_node_set *inv_eclosure = dfa->inveclosures + node;
+    re_node_set except_nodes;
+    re_node_set_init_empty (&except_nodes);
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+    {
+        Idx cur_node = inv_eclosure->elems[ecl_idx];
+        if (cur_node == node)
+            continue;
+        if (IS_EPSILON_NODE (dfa->nodes[cur_node].type))
+        {
+            Idx edst1 = dfa->edests[cur_node].elems[0];
+            Idx edst2 = ((dfa->edests[cur_node].nelem > 1)
+                         ? dfa->edests[cur_node].elems[1] : -1);
+            if ((!re_node_set_contains (inv_eclosure, edst1)
+                 && re_node_set_contains (dest_nodes, edst1))
+                || (edst2 > 0
+                    && !re_node_set_contains (inv_eclosure, edst2)
+                    && re_node_set_contains (dest_nodes, edst2)))
+            {
+                err = re_node_set_add_intersect (&except_nodes, candidates,
+                                                 dfa->inveclosures + cur_node);
+                if ( (err != REG_NOERROR))
+                {
+                    re_node_set_free (&except_nodes);
+                    return err;
+                }
+            }
+        }
+    }
+    for (ecl_idx = 0; ecl_idx < inv_eclosure->nelem; ++ecl_idx)
+    {
+        Idx cur_node = inv_eclosure->elems[ecl_idx];
+        if (!re_node_set_contains (&except_nodes, cur_node))
+        {
+            Idx idx = re_node_set_contains (dest_nodes, cur_node) - 1;
+            re_node_set_remove_at (dest_nodes, idx);
+        }
+    }
+    re_node_set_free (&except_nodes);
+    return REG_NOERROR;
+}
+
+static bool
+check_dst_limits (const re_match_context_t *mctx, const re_node_set *limits,
+                  Idx dst_node, Idx dst_idx, Idx src_node, Idx src_idx)
+{
+    const re_dfa_t *const dfa = mctx->dfa;
+    Idx lim_idx, src_pos, dst_pos;
+
+    Idx dst_bkref_idx = search_cur_bkref_entry (mctx, dst_idx);
+    Idx src_bkref_idx = search_cur_bkref_entry (mctx, src_idx);
+    for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+        Idx subexp_idx;
+        struct re_backref_cache_entry *ent;
+        ent = mctx->bkref_ents + limits->elems[lim_idx];
+        subexp_idx = dfa->nodes[ent->node].opr.idx;
+
+        dst_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+                                             subexp_idx, dst_node, dst_idx,
+                                             dst_bkref_idx);
+        src_pos = check_dst_limits_calc_pos (mctx, limits->elems[lim_idx],
+                                             subexp_idx, src_node, src_idx,
+                                             src_bkref_idx);
+
+        /* In case of:
+       <src> <dst> ( <subexp> )
+       ( <subexp> ) <src> <dst>
+       ( <subexp1> <src> <subexp2> <dst> <subexp3> )  */
+        if (src_pos == dst_pos)
+            continue; /* This is unrelated limitation.  */
+        else
+            return true;
+    }
+    return false;
+}
+
+static int
+check_dst_limits_calc_pos_1 (const re_match_context_t *mctx, int boundaries,
+                             Idx subexp_idx, Idx from_node, Idx bkref_idx)
+{
+    const re_dfa_t *const dfa = mctx->dfa;
+    const re_node_set *eclosures = dfa->eclosures + from_node;
+    Idx node_idx;
+
+    /* Else, we are on the boundary: examine the nodes on the epsilon
+       closure.  */
+    for (node_idx = 0; node_idx < eclosures->nelem; ++node_idx)
+    {
+        Idx node = eclosures->elems[node_idx];
+        switch (dfa->nodes[node].type)
+        {
+            case OP_BACK_REF:
+                if (bkref_idx != -1)
+                {
+                    struct re_backref_cache_entry *ent = mctx->bkref_ents + bkref_idx;
+                    do
+                    {
+                        Idx dst;
+                        int cpos;
+
+                        if (ent->node != node)
+                            continue;
+
+                        if (subexp_idx < BITSET_WORD_BITS
+                            && !(ent->eps_reachable_subexps_map
+                                 & ((bitset_word_t) 1 << subexp_idx)))
+                            continue;
+
+                        /* Recurse trying to reach the OP_OPEN_SUBEXP and
+                           OP_CLOSE_SUBEXP cases below.  But, if the
+                           destination node is the same node as the source
+                           node, don't recurse because it would cause an
+                           infinite loop: a regex that exhibits this behavior
+                           is ()\1*\1*  */
+                        dst = dfa->edests[node].elems[0];
+                        if (dst == from_node)
+                        {
+                            if (boundaries & 1)
+                                return -1;
+                            else /* if (boundaries & 2) */
+                                return 0;
+                        }
+
+                        cpos =
+                                check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+                                                             dst, bkref_idx);
+                        if (cpos == -1 /* && (boundaries & 1) */)
+                            return -1;
+                        if (cpos == 0 && (boundaries & 2))
+                            return 0;
+
+                        if (subexp_idx < BITSET_WORD_BITS)
+                            ent->eps_reachable_subexps_map
+                                    &= ~((bitset_word_t) 1 << subexp_idx);
+                    }
+                    while (ent++->more);
+                }
+                break;
+
+            case OP_OPEN_SUBEXP:
+                if ((boundaries & 1) && subexp_idx == dfa->nodes[node].opr.idx)
+                    return -1;
+                break;
+
+            case OP_CLOSE_SUBEXP:
+                if ((boundaries & 2) && subexp_idx == dfa->nodes[node].opr.idx)
+                    return 0;
+                break;
+
+            default:
+                break;
+        }
+    }
+
+    return (boundaries & 2) ? 1 : 0;
+}
+
+static int
+check_dst_limits_calc_pos (const re_match_context_t *mctx, Idx limit,
+                           Idx subexp_idx, Idx from_node, Idx str_idx,
+                           Idx bkref_idx)
+{
+    struct re_backref_cache_entry *lim = mctx->bkref_ents + limit;
+    int boundaries;
+
+    /* If we are outside the range of the subexpression, return -1 or 1.  */
+    if (str_idx < lim->subexp_from)
+        return -1;
+
+    if (lim->subexp_to < str_idx)
+        return 1;
+
+    /* If we are within the subexpression, return 0.  */
+    boundaries = (str_idx == lim->subexp_from);
+    boundaries |= (str_idx == lim->subexp_to) << 1;
+    if (boundaries == 0)
+        return 0;
+
+    /* Else, examine epsilon closure.  */
+    return check_dst_limits_calc_pos_1 (mctx, boundaries, subexp_idx,
+                                        from_node, bkref_idx);
+}
+
+/* Check the limitations of sub expressions LIMITS, and remove the nodes
+   which are against limitations from DEST_NODES. */
+
+static reg_errcode_t
+check_subexp_limits (const re_dfa_t *dfa, re_node_set *dest_nodes,
+                     const re_node_set *candidates, re_node_set *limits,
+                     struct re_backref_cache_entry *bkref_ents, Idx str_idx)
+{
+    reg_errcode_t err;
+    Idx node_idx, lim_idx;
+
+    for (lim_idx = 0; lim_idx < limits->nelem; ++lim_idx)
+    {
+        Idx subexp_idx;
+        struct re_backref_cache_entry *ent;
+        ent = bkref_ents + limits->elems[lim_idx];
+
+        if (str_idx <= ent->subexp_from || ent->str_idx < str_idx)
+            continue; /* This is unrelated limitation.  */
+
+        subexp_idx = dfa->nodes[ent->node].opr.idx;
+        if (ent->subexp_to == str_idx)
+        {
+            Idx ops_node = -1;
+            Idx cls_node = -1;
+            for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+            {
+                Idx node = dest_nodes->elems[node_idx];
+                re_token_type_t type = dfa->nodes[node].type;
+                if (type == OP_OPEN_SUBEXP
+                    && subexp_idx == dfa->nodes[node].opr.idx)
+                    ops_node = node;
+                else if (type == OP_CLOSE_SUBEXP
+                         && subexp_idx == dfa->nodes[node].opr.idx)
+                    cls_node = node;
+            }
+
+            /* Check the limitation of the open subexpression.  */
+            /* Note that (ent->subexp_to = str_idx != ent->subexp_from).  */
+            if (ops_node >= 0)
+            {
+                err = sub_epsilon_src_nodes (dfa, ops_node, dest_nodes,
+                                             candidates);
+                if ( (err != REG_NOERROR))
+                    return err;
+            }
+
+            /* Check the limitation of the close subexpression.  */
+            if (cls_node >= 0)
+                for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+                {
+                    Idx node = dest_nodes->elems[node_idx];
+                    if (!re_node_set_contains (dfa->inveclosures + node,
+                                               cls_node)
+                        && !re_node_set_contains (dfa->eclosures + node,
+                                                  cls_node))
+                    {
+                        /* It is against this limitation.
+                           Remove it form the current sifted state.  */
+                        err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+                                                     candidates);
+                        if ( (err != REG_NOERROR))
+                            return err;
+                        --node_idx;
+                    }
+                }
+        }
+        else /* (ent->subexp_to != str_idx)  */
+        {
+            for (node_idx = 0; node_idx < dest_nodes->nelem; ++node_idx)
+            {
+                Idx node = dest_nodes->elems[node_idx];
+                re_token_type_t type = dfa->nodes[node].type;
+                if (type == OP_CLOSE_SUBEXP || type == OP_OPEN_SUBEXP)
+                {
+                    if (subexp_idx != dfa->nodes[node].opr.idx)
+                        continue;
+                    /* It is against this limitation.
+                       Remove it form the current sifted state.  */
+                    err = sub_epsilon_src_nodes (dfa, node, dest_nodes,
+                                                 candidates);
+                    if ( (err != REG_NOERROR))
+                        return err;
+                }
+            }
+        }
+    }
+    return REG_NOERROR;
+}
+
+static reg_errcode_t
+
+sift_states_bkref (const re_match_context_t *mctx, re_sift_context_t *sctx,
+                   Idx str_idx, const re_node_set *candidates)
+{
+    const re_dfa_t *const dfa = mctx->dfa;
+    reg_errcode_t err;
+    Idx node_idx, node;
+    re_sift_context_t local_sctx;
+    Idx first_idx = search_cur_bkref_entry (mctx, str_idx);
+
+    if (first_idx == -1)
+        return REG_NOERROR;
+
+    local_sctx.sifted_states = NULL; /* Mark that it hasn't been initialized.  */
+
+    for (node_idx = 0; node_idx < candidates->nelem; ++node_idx)
+    {
+        Idx enabled_idx;
+        re_token_type_t type;
+        struct re_backref_cache_entry *entry;
+        node = candidates->elems[node_idx];
+        type = dfa->nodes[node].type;
+        /* Avoid infinite loop for the REs like "()\1+".  */
+        if (node == sctx->last_node && str_idx == sctx->last_str_idx)
+            continue;
+        if (type != OP_BACK_REF)
+            continue;
+
+        entry = mctx->bkref_ents + first_idx;
+        enabled_idx = first_idx;
+        do
+        {
+            Idx subexp_len;
+            Idx to_idx;
+            Idx dst_node;
+            bool ok;
+            re_dfastate_t *cur_state;
+
+            if (entry->node != node)
+                continue;
+            subexp_len = entry->subexp_to - entry->subexp_from;
+            to_idx = str_idx + subexp_len;
+            dst_node = (subexp_len ? dfa->nexts[node]
+                                   : dfa->edests[node].elems[0]);
+
+            if (to_idx > sctx->last_str_idx
+                || sctx->sifted_states[to_idx] == NULL
+                || !STATE_NODE_CONTAINS (sctx->sifted_states[to_idx], dst_node)
+                || check_dst_limits (mctx, &sctx->limits, node,
+                                     str_idx, dst_node, to_idx))
+                continue;
+
+            if (local_sctx.sifted_states == NULL)
+            {
+                local_sctx = *sctx;
+                err = re_node_set_init_copy (&local_sctx.limits, &sctx->limits);
+                if ( (err != REG_NOERROR))
+                    goto free_return;
+            }
+            local_sctx.last_node = node;
+            local_sctx.last_str_idx = str_idx;
+            ok = re_node_set_insert (&local_sctx.limits, enabled_idx);
+            if ( (! ok))
+            {
+                err = REG_ESPACE;
+                goto free_return;
+            }
+            cur_state = local_sctx.sifted_states[str_idx];
+            err = sift_states_backward (mctx, &local_sctx);
+            if ( (err != REG_NOERROR))
+                goto free_return;
+            if (sctx->limited_states != NULL)
+            {
+                err = merge_state_array (dfa, sctx->limited_states,
+                                         local_sctx.sifted_states,
+                                         str_idx + 1);
+                if ( (err != REG_NOERROR))
+                    goto free_return;
+            }
+            local_sctx.sifted_states[str_idx] = cur_state;
+            re_node_set_remove (&local_sctx.limits, enabled_idx);
+
+            /* mctx->bkref_ents may have changed, reload the pointer.  */
+            entry = mctx->bkref_ents + enabled_idx;
+        }
+        while (enabled_idx++, entry++->more);
+    }
+    err = REG_NOERROR;
+    free_return:
+    if (local_sctx.sifted_states != NULL)
+    {
+        re_node_set_free (&local_sctx.limits);
+    }
+
+    return err;
+}
+
+
+static reg_errcode_t
+transit_state_bkref(re_match_context_t *mctx, const re_node_set *nodes) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    reg_errcode_t err;
+    Idx i;
+    Idx cur_str_idx = re_string_cur_idx(&mctx->input);
+
+    for (i = 0; i < nodes->nelem; ++i) {
+        Idx dest_str_idx, prev_nelem, bkc_idx;
+        Idx node_idx = nodes->elems[i];
+        unsigned int context;
+        const re_token_t *node = dfa->nodes + node_idx;
+        re_node_set *new_dest_nodes;
+
+        /* Check whether 'node' is a backreference or not.  */
+        if (node->type != OP_BACK_REF)
+            continue;
+
+        if (node->constraint) {
+            context = re_string_context_at(&mctx->input, cur_str_idx,
+                                           mctx->eflags);
+            if (NOT_SATISFY_NEXT_CONSTRAINT(node->constraint, context))
+                continue;
+        }
+
+        /* 'node' is a backreference.
+       Check the substring which the substring matched.  */
+        bkc_idx = mctx->nbkref_ents;
+        err = get_subexp(mctx, node_idx, cur_str_idx);
+        if ((err != REG_NOERROR))
+            goto free_return;
+
+        /* And add the epsilon closures (which is 'new_dest_nodes') of
+       the backreference to appropriate state_log.  */
+
+        for (; bkc_idx < mctx->nbkref_ents; ++bkc_idx) {
+            Idx subexp_len;
+            re_dfastate_t *dest_state;
+            struct re_backref_cache_entry *bkref_ent;
+            bkref_ent = mctx->bkref_ents + bkc_idx;
+            if (bkref_ent->node != node_idx || bkref_ent->str_idx != cur_str_idx)
+                continue;
+            subexp_len = bkref_ent->subexp_to - bkref_ent->subexp_from;
+            new_dest_nodes = (subexp_len == 0
+                              ? dfa->eclosures + dfa->edests[node_idx].elems[0]
+                              : dfa->eclosures + dfa->nexts[node_idx]);
+            dest_str_idx = (cur_str_idx + bkref_ent->subexp_to
+                            - bkref_ent->subexp_from);
+            context = re_string_context_at(&mctx->input, dest_str_idx - 1,
+                                           mctx->eflags);
+            dest_state = mctx->state_log[dest_str_idx];
+            prev_nelem = ((mctx->state_log[cur_str_idx] == NULL) ? 0
+                                                                 : mctx->state_log[cur_str_idx]->nodes.nelem);
+            /* Add 'new_dest_node' to state_log.  */
+            if (dest_state == NULL) {
+                mctx->state_log[dest_str_idx]
+                        = re_acquire_state_context(&err, dfa, new_dest_nodes,
+                                                   context);
+                if ((mctx->state_log[dest_str_idx] == NULL
+                     && err != REG_NOERROR))
+                    goto free_return;
+            } else {
+                re_node_set dest_nodes;
+                err = re_node_set_init_union(&dest_nodes,
+                                             dest_state->entrance_nodes,
+                                             new_dest_nodes);
+                if ((err != REG_NOERROR)) {
+                    re_node_set_free(&dest_nodes);
+                    goto free_return;
+                }
+                mctx->state_log[dest_str_idx]
+                        = re_acquire_state_context(&err, dfa, &dest_nodes, context);
+                re_node_set_free(&dest_nodes);
+                if ((mctx->state_log[dest_str_idx] == NULL
+                     && err != REG_NOERROR))
+                    goto free_return;
+            }
+            /* We need to check recursively if the backreference can epsilon
+               transit.  */
+            if (subexp_len == 0
+                && mctx->state_log[cur_str_idx]->nodes.nelem > prev_nelem) {
+                err = check_subexp_matching_top(mctx, new_dest_nodes,
+                                                cur_str_idx);
+                if ((err != REG_NOERROR))
+                    goto free_return;
+                err = transit_state_bkref(mctx, new_dest_nodes);
+                if ((err != REG_NOERROR))
+                    goto free_return;
+            }
+        }
+    }
+    err = REG_NOERROR;
+    free_return:
+    return err;
+}
+
+/* Return the next state to which the current state STATE will transit by
+   accepting the current input byte, and update STATE_LOG if necessary.
+   If STATE can accept a multibyte char/collating element/back reference
+   update the destination of STATE_LOG.  */
+
+static re_dfastate_t *
+
+transit_state(reg_errcode_t
+              *err,
+              re_match_context_t *mctx,
+              re_dfastate_t
+              *state) {
+    re_dfastate_t **trtable;
+    unsigned char ch;
+
+/* Use transition table  */
+    ch = re_string_fetch_byte(&mctx->input);
+    for (;;) {
+        trtable = state->trtable;
+        if ((trtable != NULL))
+            return trtable[ch];
+
+        trtable = state->word_trtable;
+        if ((trtable != NULL)) {
+            unsigned int context;
+            context
+                    = re_string_context_at(&mctx->input,
+                                           re_string_cur_idx(&mctx->input) - 1,
+                                           mctx->eflags);
+            if (
+                    IS_WORD_CONTEXT(context)
+                    )
+                return trtable[ch + SBC_MAX];
+            else
+                return trtable[ch];
+        }
+
+        if (!
+                build_trtable(mctx
+                                      ->dfa, state)) {
+            *
+                    err = REG_ESPACE;
+            return
+                    NULL;
+        }
+
+/* Retry, we now have a transition table.  */
+    }
+}
+
+/* Update the state_log if we need */
+static re_dfastate_t *
+merge_state_with_log(reg_errcode_t *err, re_match_context_t *mctx,
+                     re_dfastate_t *next_state) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    Idx cur_idx = re_string_cur_idx(&mctx->input);
+
+    if (cur_idx > mctx->state_log_top) {
+        mctx->state_log[cur_idx] = next_state;
+        mctx->state_log_top = cur_idx;
+    } else if (mctx->state_log[cur_idx] == 0) {
+        mctx->state_log[cur_idx] = next_state;
+    } else {
+        re_dfastate_t *pstate;
+        unsigned int context;
+        re_node_set next_nodes, *log_nodes, *table_nodes = NULL;
+        /* If (state_log[cur_idx] != 0), it implies that cur_idx is
+       the destination of a multibyte char/collating element/
+       back reference.  Then the next state is the union set of
+       these destinations and the results of the transition table.  */
+        pstate = mctx->state_log[cur_idx];
+        log_nodes = pstate->entrance_nodes;
+        if (next_state != NULL) {
+            table_nodes = next_state->entrance_nodes;
+            *err = re_node_set_init_union(&next_nodes, table_nodes,
+                                          log_nodes);
+            if ((*err != REG_NOERROR))
+                return NULL;
+        } else
+            next_nodes = *log_nodes;
+        /* Note: We already add the nodes of the initial state,
+       then we don't need to add them here.  */
+
+        context = re_string_context_at(&mctx->input,
+                                       re_string_cur_idx(&mctx->input) - 1,
+                                       mctx->eflags);
+        next_state = mctx->state_log[cur_idx]
+                = re_acquire_state_context(err, dfa, &next_nodes, context);
+        /* We don't need to check errors here, since the return value of
+       this function is next_state and ERR is already set.  */
+
+        if (table_nodes != NULL)
+            re_node_set_free(&next_nodes);
+    }
+
+    if ((dfa->nbackref) && next_state != NULL) {
+        /* Check OP_OPEN_SUBEXP in the current state in case that we use them
+       later.  We must check them here, since the back references in the
+       next state might use them.  */
+        *err = check_subexp_matching_top(mctx, &next_state->nodes,
+                                         cur_idx);
+        if ((*err != REG_NOERROR))
+            return NULL;
+
+        /* If the next state has back references.  */
+        if (next_state->has_backref) {
+            *err = transit_state_bkref(mctx, &next_state->nodes);
+            if ((*err != REG_NOERROR))
+                return NULL;
+            next_state = mctx->state_log[cur_idx];
+        }
+    }
+
+    return next_state;
+}
+
+/* Skip bytes in the input that correspond to part of a
+   multi-byte match, then look in the log for a state
+   from which to restart matching.  */
+static re_dfastate_t *
+find_recover_state(reg_errcode_t *err, re_match_context_t *mctx) {
+    re_dfastate_t *cur_state;
+    do {
+        Idx max = mctx->state_log_top;
+        Idx cur_str_idx = re_string_cur_idx(&mctx->input);
+
+        do {
+            if (++cur_str_idx > max)
+                return NULL;
+            re_string_skip_bytes(&mctx->input, 1);
+        } while (mctx->state_log[cur_str_idx] == NULL);
+
+        cur_state = merge_state_with_log(err, mctx, NULL);
+    } while (*err == REG_NOERROR && cur_state == NULL);
+    return cur_state;
+}
+
+/* Functions for matching context.  */
+
+/* Initialize MCTX.  */
+
+static reg_errcode_t
+match_ctx_init(re_match_context_t *mctx, int eflags, Idx n) {
+    mctx->eflags = eflags;
+    mctx->match_last = -1;
+    if (n > 0) {
+/* Avoid overflow.  */
+        size_t max_object_size =
+                MAX (sizeof(struct re_backref_cache_entry),
+                     sizeof(re_sub_match_top_t * ));
+        if ((MIN (IDX_MAX, SIZE_MAX / max_object_size) < n))
+            return REG_ESPACE;
+
+        mctx->bkref_ents = re_malloc(
+        struct re_backref_cache_entry, n);
+        mctx->sub_tops = re_malloc(re_sub_match_top_t * , n);
+        if ((mctx->bkref_ents == NULL || mctx->sub_tops == NULL))
+            return REG_ESPACE;
+    }
+/* Already zero-ed by the caller.
+   else
+     mctx->bkref_ents = NULL;
+   mctx->nbkref_ents = 0;
+   mctx->nsub_tops = 0;  */
+    mctx->abkref_ents = n;
+    mctx->max_mb_elem_len = 1;
+    mctx->asub_tops = n;
+    return REG_NOERROR;
+}
+
+/* Clean the entries which depend on the current input in MCTX.
+   This function must be invoked when the matcher changes the start index
+   of the input, or changes the input string.  */
+
+static void
+match_ctx_clean(re_match_context_t *mctx) {
+    Idx st_idx;
+    for (st_idx = 0; st_idx < mctx->nsub_tops; ++st_idx) {
+        Idx sl_idx;
+        re_sub_match_top_t *top = mctx->sub_tops[st_idx];
+        for (sl_idx = 0; sl_idx < top->nlasts; ++sl_idx) {
+            re_sub_match_last_t *last = top->lasts[sl_idx];
+            re_free(last->path.array);
+            re_free(last);
+        }
+        re_free(top->lasts);
+        if (top->path) {
+            re_free(top->path->array);
+            re_free(top->path);
+        }
+        re_free(top);
+    }
+
+    mctx->nsub_tops = 0;
+    mctx->nbkref_ents = 0;
+}
+
+/* Free all the memory associated with MCTX.  */
+
+static void
+match_ctx_free(re_match_context_t *mctx) {
+    /* First, free all the memory associated with MCTX->SUB_TOPS.  */
+    match_ctx_clean(mctx);
+    re_free(mctx->sub_tops);
+    re_free(mctx->bkref_ents);
+}
+
+/* Add a new backreference entry to MCTX.
+   Note that we assume that caller never call this function with duplicate
+   entry, and call with STR_IDX which isn't smaller than any existing entry.
+*/
+
+static reg_errcode_t
+
+match_ctx_add_entry(re_match_context_t *mctx, Idx node, Idx str_idx, Idx from,
+                    Idx to) {
+    if (mctx->nbkref_ents >= mctx->abkref_ents) {
+        struct re_backref_cache_entry *new_entry;
+        new_entry = re_realloc(mctx->bkref_ents,
+        struct re_backref_cache_entry,
+        mctx->abkref_ents * 2);
+        if ((new_entry == NULL)) {
+            re_free(mctx->bkref_ents);
+            return REG_ESPACE;
+        }
+        mctx->bkref_ents = new_entry;
+        memset(mctx->bkref_ents + mctx->nbkref_ents, '\0',
+               sizeof(struct re_backref_cache_entry) * mctx->abkref_ents);
+        mctx->abkref_ents *= 2;
+    }
+    if (mctx->nbkref_ents > 0
+        && mctx->bkref_ents[mctx->nbkref_ents - 1].str_idx == str_idx)
+        mctx->bkref_ents[mctx->nbkref_ents - 1].more = 1;
+
+    mctx->bkref_ents[mctx->nbkref_ents].node = node;
+    mctx->bkref_ents[mctx->nbkref_ents].str_idx = str_idx;
+    mctx->bkref_ents[mctx->nbkref_ents].subexp_from = from;
+    mctx->bkref_ents[mctx->nbkref_ents].subexp_to = to;
+
+/* This is a cache that saves negative results of check_dst_limits_calc_pos.
+   If bit N is clear, means that this entry won't epsilon-transition to
+   an OP_OPEN_SUBEXP or OP_CLOSE_SUBEXP for the N+1-th subexpression.  If
+   it is set, check_dst_limits_calc_pos_1 will recurse and try to find one
+   such node.
+
+   A backreference does not epsilon-transition unless it is empty, so set
+   to all zeros if FROM != TO.  */
+    mctx->bkref_ents[mctx->nbkref_ents].eps_reachable_subexps_map
+            = (from == to ? -1 : 0);
+
+    mctx->bkref_ents[mctx->nbkref_ents++].more = 0;
+    if (mctx->max_mb_elem_len < to - from)
+        mctx->max_mb_elem_len = to - from;
+    return REG_NOERROR;
+}
+
+/* Check whether the regular expression match input string INPUT or not,
+   and return the index where the matching end.  Return -1 if
+   there is no match, and return -2 in case of an error.
+   FL_LONGEST_MATCH means we want the POSIX longest matching.
+   If P_MATCH_FIRST is not NULL, and the match fails, it is set to the
+   next place where we may want to try matching.
+   Note that the matcher assumes that the matching starts from the current
+   index of the buffer.  */
+
+static Idx
+check_matching(re_match_context_t *mctx, bool fl_longest_match,
+               Idx *p_match_first) {
+    const re_dfa_t *const dfa = mctx->dfa;
+    reg_errcode_t err;
+    Idx match = 0;
+    Idx match_last = -1;
+    Idx cur_str_idx = re_string_cur_idx(&mctx->input);
+    re_dfastate_t *cur_state;
+    bool at_init_state = p_match_first != NULL;
+    Idx next_start_idx = cur_str_idx;
+
+    err = REG_NOERROR;
+    cur_state = acquire_init_state_context(&err, mctx, cur_str_idx);
+/* An initial state must not be NULL (invalid).  */
+    if ((cur_state == NULL)) {
+        assert(err == REG_ESPACE);
+        return -2;
+    }
+
+    if (mctx->state_log != NULL) {
+        mctx->state_log[cur_str_idx] = cur_state;
+
+/* Check OP_OPEN_SUBEXP in the initial state in case that we use them
+later.  E.g. Processing back references.  */
+        if ((dfa->nbackref)) {
+            at_init_state = false;
+            err = check_subexp_matching_top(mctx, &cur_state->nodes, 0);
+            if ((err != REG_NOERROR))
+                return err;
+
+            if (cur_state->has_backref) {
+                err = transit_state_bkref(mctx, &cur_state->nodes);
+                if ((err != REG_NOERROR))
+                    return err;
+            }
+        }
+    }
+
+/* If the RE accepts NULL string.  */
+    if ((cur_state->halt)) {
+        if (!cur_state->has_constraint
+            || check_halt_state_context(mctx, cur_state, cur_str_idx)) {
+            if (!fl_longest_match)
+                return cur_str_idx;
+            else {
+                match_last = cur_str_idx;
+                match = 1;
+            }
+        }
+    }
+
+    while (!re_string_eoi(&mctx->input)) {
+        re_dfastate_t *old_state = cur_state;
+        Idx next_char_idx = re_string_cur_idx(&mctx->input) + 1;
+
+        if (((next_char_idx >= mctx->input.bufs_len)
+             && mctx->input.bufs_len < mctx->input.len)
+            || ((next_char_idx >= mctx->input.valid_len)
+                && mctx->input.valid_len < mctx->input.len)) {
+            err = extend_buffers(mctx, next_char_idx + 1);
+            if ((err != REG_NOERROR)) {
+                assert(err == REG_ESPACE);
+                return -2;
+            }
+        }
+
+        cur_state = transit_state(&err, mctx, cur_state);
+        if (mctx->state_log != NULL)
+            cur_state = merge_state_with_log(&err, mctx, cur_state);
+
+        if (cur_state == NULL) {
+/* Reached the invalid state or an error.  Try to recover a valid
+   state using the state log, if available and if we have not
+   already found a valid (even if not the longest) match.  */
+            if ((err != REG_NOERROR))
+                return -2;
+
+            if (mctx->state_log == NULL
+                || (match && !fl_longest_match)
+                || (cur_state = find_recover_state(&err, mctx)) == NULL)
+                break;
+        }
+
+        if ((at_init_state)) {
+            if (old_state == cur_state)
+                next_start_idx = next_char_idx;
+            else
+                at_init_state = false;
+        }
+
+        if (cur_state->halt) {
+/* Reached a halt state.
+   Check the halt state can satisfy the current context.  */
+            if (!cur_state->has_constraint
+                || check_halt_state_context(mctx, cur_state,
+                                            re_string_cur_idx(&mctx->input))) {
+/* We found an appropriate halt state.  */
+                match_last = re_string_cur_idx(&mctx->input);
+                match = 1;
+
+/* We found a match, do not modify match_first below.  */
+                p_match_first = NULL;
+                if (!fl_longest_match)
+                    break;
+            }
+        }
+    }
+
+    if (p_match_first)
+        *p_match_first += next_start_idx;
+
+    return match_last;
+}
+
+/* Searches for a compiled pattern PREG in the string STRING, whose
+   length is LENGTH.  NMATCH, PMATCH, and EFLAGS have the same
+   meaning as with regexec.  LAST_START is START + RANGE, where
+   START and RANGE have the same meaning as with re_search.
+   Return REG_NOERROR if we find a match, and REG_NOMATCH if not,
+   otherwise return the error code.
+   Note: We assume front end functions already check ranges.
+   (0 <= LAST_START && LAST_START <= LENGTH)  */
+
+static reg_errcode_t
+re_search_internal(const regex_t *preg, const char *string, Idx length,
+                   Idx start, Idx last_start, Idx stop, size_t nmatch,
+                   regmatch_t pmatch[], int eflags) {
+    reg_errcode_t err;
+    const re_dfa_t *dfa = preg->buffer;
+    Idx left_lim, right_lim;
+    int incr;
+    bool fl_longest_match;
+    int match_kind;
+    Idx match_first;
+    Idx match_last = -1;
+    Idx extra_nmatch;
+    bool sb;
+    int ch;
+    re_match_context_t mctx;
+    char *fastmap = ((preg->fastmap != NULL && preg->fastmap_accurate
+                      && start != last_start && !preg->can_be_null)
+                     ? preg->fastmap : NULL);
+    RE_TRANSLATE_TYPE t = preg->translate;
+
+    memset(&mctx, '\0', sizeof(re_match_context_t));
+    mctx.dfa = dfa;
+
+
+    extra_nmatch = (nmatch > preg->re_nsub) ? nmatch - (preg->re_nsub + 1) : 0;
+    nmatch -= extra_nmatch;
+
+    /* Check if the DFA haven't been compiled.  */
+    if ((preg->used == 0 || dfa->init_state == NULL
+         || dfa->init_state_word == NULL
+         || dfa->init_state_nl == NULL
+         || dfa->init_state_begbuf == NULL))
+        return REG_NOMATCH;
+
+    /* If initial states with non-begbuf contexts have no elements,
+       the regex must be anchored.  If preg->newline_anchor is set,
+       we'll never use init_state_nl, so do not check it.  */
+    if (dfa->init_state->nodes.nelem == 0
+        && dfa->init_state_word->nodes.nelem == 0
+        && (dfa->init_state_nl->nodes.nelem == 0
+            || !preg->newline_anchor)) {
+        if (start != 0 && last_start != 0)
+            return REG_NOMATCH;
+        start = last_start = 0;
+    }
+
+    /* We must check the longest matching, if nmatch > 0.  */
+    fl_longest_match = (nmatch != 0 || dfa->nbackref);
+
+    err = re_string_allocate(&mctx.input, string, length, dfa->nodes_len + 1,
+                             preg->translate, (preg->syntax & RE_ICASE) != 0,
+                             dfa);
+    if ((err != REG_NOERROR))
+        goto free_return;
+    mctx.input.stop = stop;
+    mctx.input.raw_stop = stop;
+    mctx.input.newline_anchor = preg->newline_anchor;
+
+    err = match_ctx_init(&mctx, eflags, dfa->nbackref * 2);
+    if ((err != REG_NOERROR))
+        goto free_return;
+
+    /* We will log all the DFA states through which the dfa pass,
+       if nmatch > 1, or this dfa has "multibyte node", which is a
+       back-reference or a node which can accept multibyte character or
+       multi character collating element.  */
+    if (nmatch > 1 || dfa->has_mb_node) {
+        /* Avoid overflow.  */
+        if (((MIN (IDX_MAX, SIZE_MAX / sizeof(re_dfastate_t * ))
+              <= mctx.input.bufs_len))) {
+            err = REG_ESPACE;
+            goto free_return;
+        }
+
+        mctx.state_log = re_malloc(re_dfastate_t * , mctx.input.bufs_len + 1);
+        if ((mctx.state_log == NULL)) {
+            err = REG_ESPACE;
+            goto free_return;
+        }
+    } else
+        mctx.state_log = NULL;
+
+    match_first = start;
+    mctx.input.tip_context = (eflags & REG_NOTBOL) ? CONTEXT_BEGBUF
+                                                   : CONTEXT_NEWLINE | CONTEXT_BEGBUF;
+
+    /* Check incrementally whether the input string matches.  */
+    incr = (last_start < start) ? -1 : 1;
+    left_lim = (last_start < start) ? last_start : start;
+    right_lim = (last_start < start) ? start : last_start;
+    sb = dfa->mb_cur_max == 1;
+    match_kind =
+            (fastmap
+             ? ((sb || !(preg->syntax & RE_ICASE || t) ? 4 : 0)
+                | (start <= last_start ? 2 : 0)
+                | (t != NULL ? 1 : 0))
+             : 8);
+
+    for (;; match_first += incr) {
+        err = REG_NOMATCH;
+        if (match_first < left_lim || right_lim < match_first)
+            goto free_return;
+
+        /* Advance as rapidly as possible through the string, until we
+       find a plausible place to start matching.  This may be done
+       with varying efficiency, so there are various possibilities:
+       only the most common of them are specialized, in order to
+       save on code size.  We use a switch statement for speed.  */
+        switch (match_kind) {
+            case 8:
+                /* No fastmap.  */
+                break;
+
+            case 7:
+                /* Fastmap with single-byte translation, match forward.  */
+                while ((match_first < right_lim)
+                       && !fastmap[t[(unsigned char) string[match_first]]])
+                    ++match_first;
+                goto forward_match_found_start_or_reached_end;
+
+            case 6:
+                /* Fastmap without translation, match forward.  */
+                while ((match_first < right_lim)
+                       && !fastmap[(unsigned char) string[match_first]])
+                    ++match_first;
+
+            forward_match_found_start_or_reached_end:
+                if ((match_first == right_lim)) {
+                    ch = match_first >= length
+                         ? 0 : (unsigned char) string[match_first];
+                    if (!fastmap[t ? t[ch] : ch])
+                        goto free_return;
+                }
+                break;
+
+            case 4:
+            case 5:
+                /* Fastmap without multi-byte translation, match backwards.  */
+                while (match_first >= left_lim) {
+                    ch = match_first >= length
+                         ? 0 : (unsigned char) string[match_first];
+                    if (fastmap[t ? t[ch] : ch])
+                        break;
+                    --match_first;
+                }
+                if (match_first < left_lim)
+                    goto free_return;
+                break;
+
+            default:
+                /* In this case, we can't determine easily the current byte,
+                   since it might be a component byte of a multibyte
+                   character.  Then we use the constructed buffer instead.  */
+                for (;;) {
+                    /* If MATCH_FIRST is out of the valid range, reconstruct the
+                   buffers.  */
+                    __re_size_t offset = match_first - mctx.input.raw_mbs_idx;
+                    if ((offset
+                         >= (__re_size_t) mctx.input.valid_raw_len)) {
+                        err = re_string_reconstruct(&mctx.input, match_first,
+                                                    eflags);
+                        if ((err != REG_NOERROR))
+                            goto free_return;
+
+                        offset = match_first - mctx.input.raw_mbs_idx;
+                    }
+                    /* If MATCH_FIRST is out of the buffer, leave it as '\0'.
+                   Note that MATCH_FIRST must not be smaller than 0.  */
+                    ch = (match_first >= length
+                          ? 0 : re_string_byte_at(&mctx.input, offset));
+                    if (fastmap[ch])
+                        break;
+                    match_first += incr;
+                    if (match_first < left_lim || match_first > right_lim) {
+                        err = REG_NOMATCH;
+                        goto free_return;
+                    }
+                }
+                break;
+        }
+
+        /* Reconstruct the buffers so that the matcher can assume that
+       the matching starts from the beginning of the buffer.  */
+        err = re_string_reconstruct(&mctx.input, match_first, eflags);
+        if ((err != REG_NOERROR))
+            goto free_return;
+
+        /* It seems to be appropriate one, then use the matcher.  */
+        /* We assume that the matching starts from 0.  */
+        mctx.state_log_top = mctx.nbkref_ents = mctx.max_mb_elem_len = 0;
+        match_last = check_matching(&mctx, fl_longest_match,
+                                    start <= last_start ? &match_first : NULL);
+        if (match_last != -1) {
+            if ((match_last == -2)) {
+                err = REG_ESPACE;
+                goto free_return;
+            } else {
+                mctx.match_last = match_last;
+                if ((!preg->no_sub && nmatch > 1) || dfa->nbackref) {
+                    re_dfastate_t *pstate = mctx.state_log[match_last];
+                    mctx.last_node = check_halt_state_context(&mctx, pstate,
+                                                              match_last);
+                }
+                if ((!preg->no_sub && nmatch > 1 && dfa->has_plural_match)
+                    || dfa->nbackref) {
+                    err = prune_impossible_nodes(&mctx);
+                    if (err == REG_NOERROR)
+                        break;
+                    if ((err != REG_NOMATCH))
+                        goto free_return;
+                    match_last = -1;
+                } else
+                    break; /* We found a match.  */
+            }
+        }
+
+        match_ctx_clean(&mctx);
+    }
+
+    /* Set pmatch[] if we need.  */
+    if (nmatch > 0) {
+        Idx reg_idx;
+
+        /* Initialize registers.  */
+        for (reg_idx = 1; reg_idx < nmatch; ++reg_idx)
+            pmatch[reg_idx].rm_so = pmatch[reg_idx].rm_eo = -1;
+
+        /* Set the points where matching start/end.  */
+        pmatch[0].rm_so = 0;
+        pmatch[0].rm_eo = mctx.match_last;
+        /* FIXME: This function should fail if mctx.match_last exceeds
+       the maximum possible regoff_t value.  We need a new error
+       code REG_OVERFLOW.  */
+
+        if (!preg->no_sub && nmatch > 1) {
+            err = set_regs(preg, &mctx, nmatch, pmatch,
+                           dfa->has_plural_match && dfa->nbackref > 0);
+            if ((err != REG_NOERROR))
+                goto free_return;
+        }
+
+        /* At last, add the offset to each register, since we slid
+       the buffers so that we could assume that the matching starts
+       from 0.  */
+        for (reg_idx = 0; reg_idx < nmatch; ++reg_idx)
+            if (pmatch[reg_idx].rm_so != -1) {
+                pmatch[reg_idx].rm_so += match_first;
+                pmatch[reg_idx].rm_eo += match_first;
+            }
+        for (reg_idx = 0; reg_idx < extra_nmatch; ++reg_idx) {
+            pmatch[nmatch + reg_idx].rm_so = -1;
+            pmatch[nmatch + reg_idx].rm_eo = -1;
+        }
+
+        if (dfa->subexp_map)
+            for (reg_idx = 0; reg_idx + 1 < nmatch; reg_idx++)
+                if (dfa->subexp_map[reg_idx] != reg_idx) {
+                    pmatch[reg_idx + 1].rm_so
+                            = pmatch[dfa->subexp_map[reg_idx] + 1].rm_so;
+                    pmatch[reg_idx + 1].rm_eo
+                            = pmatch[dfa->subexp_map[reg_idx] + 1].rm_eo;
+                }
+    }
+
+    free_return:
+    re_free(mctx.state_log);
+    if (dfa->nbackref)
+        match_ctx_free(&mctx);
+    re_string_destruct(&mctx.input);
+    return err;
+}
+
+/* Helper functions.  */
+
+static reg_errcode_t
+merge_state_array (const re_dfa_t *dfa, re_dfastate_t **dst,
+                   re_dfastate_t **src, Idx num)
+{
+    Idx st_idx;
+    reg_errcode_t err;
+    for (st_idx = 0; st_idx < num; ++st_idx)
+    {
+        if (dst[st_idx] == NULL)
+            dst[st_idx] = src[st_idx];
+        else if (src[st_idx] != NULL)
+        {
+            re_node_set merged_set;
+            err = re_node_set_init_union (&merged_set, &dst[st_idx]->nodes,
+                                          &src[st_idx]->nodes);
+            if ( (err != REG_NOERROR))
+                return err;
+            dst[st_idx] = re_acquire_state (&err, dfa, &merged_set);
+            re_node_set_free (&merged_set);
+            if ( (err != REG_NOERROR))
+                return err;
+        }
+    }
+    return REG_NOERROR;
+}
+
+static void
+sift_ctx_init (re_sift_context_t *sctx, re_dfastate_t **sifted_sts,
+               re_dfastate_t **limited_sts, Idx last_node, Idx last_str_idx)
+{
+    sctx->sifted_states = sifted_sts;
+    sctx->limited_states = limited_sts;
+    sctx->last_node = last_node;
+    sctx->last_str_idx = last_str_idx;
+    re_node_set_init_empty (&sctx->limits);
+}
+
+
+/* regexec searches for a given pattern, specified by PREG, in the
+   string STRING.
+
+   If NMATCH is zero or REG_NOSUB was set in the cflags argument to
+   'regcomp', we ignore PMATCH.  Otherwise, we assume PMATCH has at
+   least NMATCH elements, and we set them to the offsets of the
+   corresponding matched substrings.
+
+   EFLAGS specifies "execution flags" which affect matching: if
+   REG_NOTBOL is set, then ^ does not match at the beginning of the
+   string; if REG_NOTEOL is set, then $ does not match at the end.
+
+   We return 0 if we find a match and REG_NOMATCH if not.  */
+
+int
+regexec(const regex_t *_Restrict_ preg, const char *_Restrict_ string,
+        size_t nmatch, regmatch_t pmatch[], int eflags) {
+    reg_errcode_t err;
+    Idx start, length;
+    re_dfa_t *dfa = preg->buffer;
+
+    if (eflags & ~(REG_NOTBOL | REG_NOTEOL | REG_STARTEND))
+        return REG_BADPAT;
+
+    if (eflags & REG_STARTEND) {
+        start = pmatch[0].rm_so;
+        length = pmatch[0].rm_eo;
+    } else {
+        start = 0;
+        length = strlen(string);
+    }
+
+    lock_lock(dfa->lock);
+    if (preg->no_sub)
+        err = re_search_internal(preg, string, length, start, length,
+                                 length, 0, NULL, eflags);
+    else
+        err = re_search_internal(preg, string, length, start, length,
+                                 length, nmatch, pmatch, eflags);
+    lock_unlock(dfa->lock);
+    return err != REG_NOERROR;
+}
+
+#endif
diff --git a/wait.h b/wait.h
index 7408d15..3bea227 100644
--- a/wait.h
+++ b/wait.h
@@ -26,3 +26,7 @@

+#ifdef HAVE_SYS_WAIT_H
 #include <sys/wait.h>
+#else
+#include "headers-mingw/sys_wait.h"
+#endif

