--- lib/os2-emx.c	Thu Jan  1 00:00:00 1970
+++ lib/os2-emx.c	Tue Nov 25 21:03:04 2008
@@ -0,0 +1,51 @@
+#ifdef __EMX__
+
+#include <config.h>
+#include <string.h>
+
+#define INCL_BASE
+#define INCL_NOPM
+#include <os2.h>
+
+/*------------------------------------------------------------------.
+| Fill the buffer with the startup path containing the executable.  |
+`------------------------------------------------------------------*/
+
+void query_startup_dir(char *dest)
+{
+  PTIB ptib;
+  PIB *ppib;
+  int i, j=-1;
+
+  DosGetInfoBlocks(&ptib, &ppib);
+  DosQueryModuleName(ppib->pib_hmte, CCHMAXPATH, dest);
+  for(i=0; dest[i]!='\0'; i++)
+  {
+     if(dest[i]=='\\')
+     {
+       dest[i]='/';
+       j=i;
+     }
+  }
+  if(j<0)
+  {
+    dest[0]='.';
+    j=1;
+  }
+  dest[j]='\0';
+}
+
+/*--------------------------------------------------------------.
+| Check to see if the given filename is an existing directory.  |
+`--------------------------------------------------------------*/
+
+int is_directory(char *name)
+{
+  FILESTATUS3 fstatus;
+  int rc;
+
+  rc=DosQueryPathInfo(name, FIL_STANDARD, (PBYTE)&fstatus, sizeof(fstatus));
+  return(rc?0:(fstatus.attrFile&FILE_DIRECTORY));
+}
+
+#endif
--- lib/os2-emx.h	Thu Jan  1 00:00:00 1970
+++ lib/os2-emx.h	Tue Nov 25 19:59:00 2008
@@ -0,0 +1,4 @@
+#ifdef __EMX__
+void query_startup_dir(char *dest);
+int is_directory(char *name);
+#endif
--- lib/Makefile.am	Mon Jul 14 02:56:24 2008
+++ lib/Makefile.am	Tue Nov 25 20:21:46 2008
@@ -36,6 +36,7 @@
 # Non-gnulib sources in Bison's internal library.
 libbison_a_SOURCES += \
   get-errno.h get-errno.c \
+  os2-emx.h os2-emx.c \
   subpipe.h subpipe.c \
   $(bitsets_sources) $(additional_bitsets_sources) $(timevars_sources)
 
--- src/output.c	Sun Nov  2 11:09:20 2008
+++ src/output.c	Tue Nov 25 22:25:58 2008
@@ -27,6 +27,7 @@
 #include <quotearg.h>
 #include <subpipe.h>
 #include <timevar.h>
+#include <os2-emx.h>
 
 #include "complain.h"
 #include "files.h"
@@ -40,7 +41,6 @@
 #include "symtab.h"
 #include "tables.h"
 
-
 static struct obstack format_obstack;
 
 
@@ -483,10 +483,32 @@
   char *full_m4bison;
   char *full_skeleton;
   char const *p;
+#ifdef __EMX__
+  char m4[512];
+#else
   char const *m4 = (p = getenv ("M4")) ? p : M4;
+#endif
   char const *pkgdatadir = compute_pkgdatadir ();
   size_t skeleton_size = strlen (skeleton) + 1;
   size_t pkgdatadirlen = strlen (pkgdatadir);
+  
+#ifdef __EMX__
+  /* Search for M4 the OS/2 way */
+  if ((p = getenv("M4")) != NULL)
+  {
+    strcpy(m4, p);
+  }
+  else
+  {
+    m4[0] = '\0';
+    _searchenv ("m4.exe", "PATH", m4);
+    if (m4[0] == '\0')
+    {
+      query_startup_dir(m4);
+      strcat (m4, "/m4.exe");
+    }
+  }
+#endif
   while (pkgdatadirlen && pkgdatadir[pkgdatadirlen - 1] == '/')
     pkgdatadirlen--;
   full_skeleton = xmalloc (pkgdatadirlen + 1
@@ -668,9 +690,47 @@
   obstack_free (&format_obstack, NULL);
 }
 
+
 char const *
 compute_pkgdatadir (void)
 {
   char const *pkgdatadir = getenv ("BISON_PKGDATADIR");
+
+#ifdef __EMX__
+  static char *os2_pkgopts[] = {"lib/bison", "bison-data", "data", NULL};
+  static char os2_pkgdatadir[512]={0};
+  char *p;
+  int i;
+  
+  if (pkgdatadir)
+  {
+    return pkgdatadir;
+  }
+  else
+  {
+    /* Already computed => return it */
+    if(os2_pkgdatadir[0])
+      return os2_pkgdatadir;
+    query_startup_dir(os2_pkgdatadir);
+    if ((p = strrchr(os2_pkgdatadir, '/')) == NULL)
+    {
+      /* Current directory, try the immediate parent */
+      strcpy (os2_pkgdatadir, "../");
+      p = os2_pkgdatadir + strlen(os2_pkgdatadir);
+    }
+    else
+      p++;
+    /* Try the possible paths */
+    for(i = 0; os2_pkgopts[i] != NULL; i++)
+    {
+      strcpy(p, os2_pkgopts[i]);
+      if(is_directory(os2_pkgdatadir))
+        return(os2_pkgdatadir);
+    }
+    query_startup_dir(os2_pkgdatadir);
+    return(os2_pkgdatadir);
+  }
+#else
   return pkgdatadir ? pkgdatadir : PKGDATADIR;
+#endif
 }
