Index: trunk/src/emx/src/emxomf/emxomfld.c
===================================================================
--- trunk/src/emx/src/emxomf/emxomfld.c	(revision 652)
+++ trunk/src/emx/src/emxomf/emxomfld.c	(revision 653)
@@ -117,8 +117,8 @@
 
 /* Weak alias object file. */
-static char weakobj_fname[_MAX_PATH];
+static char weakobj_fname[_MAX_PATH + 1];
 
 /* Weak definition file (modified def_fname). */
-static char weakdef_fname[_MAX_PATH];
+static char weakdef_fname[_MAX_PATH + 1];
 
 /* Non-zero if debugging information is to be omitted.  Set by the -s
@@ -460,5 +460,5 @@
   for (list = libdirs; list != NULL; list = list->next)
     {
-      if (tmp[len-1] != ';')
+      if (list != libdirs && tmp[len-1] != ';')
         tmp[len++] = ';';
       strcpy (tmp+len, list->name);
@@ -486,143 +486,151 @@
 }
 
-
-/* finds the full path of a library or object file, after check
-   default extentions an such.
-
-   Object files will be searched for using the LIB env.var if not found.
-
-   Library hacks:
-     1. file with .lib extention.
-     2. file with .lib extention and lib prefix.
-     3. file with .a extention which is an OMF library.
-     4. file with .a extention and lib prefix which is an OMF library.
-   */
-
-static FILE * find_objlib2(char *pszfullname, const char *pszname, const char * const *papszexts, int flibhacks)
-{
-  const char *  psz;
-  char *        psz2;
-  int           cch;
-  int           i;
-  int           fextension;
-  FILE *        phFile;
-  char          cchname = strlen (pszname);
-
-  /* Plain name first - the easist option */
-  memcpy (pszfullname, pszname, cchname + 1);
-  phFile = fopen (pszfullname, "rb");
-  if (phFile)
-    return phFile;
-
-  /* Plain name with all extentions. */
-  psz = strrchr (pszname, '.');
-  fextension = (psz && !strpbrk (psz, ":\\/"));
-  if (!fextension)
-    {
-      psz2 = pszfullname + cchname;
-      for (i = 0; papszexts[i]; i++)
-        {
-          strcpy (psz2, papszexts[i]);
-          phFile = fopen (pszfullname, "rb");
-          if (phFile)
-            return phFile;
-        }
-    }
-
-  /* Search LIBS. */
-  if (!strpbrk (pszname, ":\\/"))
-    {
-      int           ffound;
-      const char *  pszend;
-      for (psz = getenv("LIB"), ffound = 0; !ffound && psz; psz = pszend + (pszend != NULL))
-        {
-          pszend = strchr(psz, ';');
-          if (pszend <= psz)
-              continue;
-
-          /* normalize the name */
-          cch = pszend - psz;
-          memcpy(pszfullname, psz, pszend - psz);
-          if (   pszfullname[cch-1] != '\\'
-              && pszfullname[cch-1] != '/'
-              && pszfullname[cch-1] != ':')
-            pszfullname[cch++] = '\\';
-          memcpy(pszfullname + cch, pszname, cchname + 1);
-
-          if (!fextension)
+/* Check if the given file is a valid OMF library. */
+
+static int check_omf_library (FILE *f)
+{
+#pragma pack(1)
+  struct
+  {
+    byte rec_type;
+    word rec_len;
+    dword dict_offset;
+    word dict_blocks;
+    byte flags;
+  } libhdr;
+#pragma pack()
+
+  if (fread (&libhdr, 1, sizeof(libhdr), f) == sizeof (libhdr)
+   && libhdr.rec_type == LIBHDR
+   && libhdr.flags <= 1 /* ASSUME only first bit is used... */
+   && !fseek (f, 0, SEEK_SET))
+    {
+      int page_size = libhdr.rec_len + 3;
+      if (page_size >= 16
+       && page_size <= 32768
+       && !(page_size & (page_size - 1)) != 0)
+        return 1;
+    }
+
+  return 0;
+}
+
+/* finds the full path of a library or object file.
+
+   Object files and libraries will be searched for using the LIB env.var
+   (which is exported so that it is used by ILINK/LINK386 as well),
+   if not found by their path directly. Note that finding object files in
+   the LIB paths contradicts the standard Unix behaviour, so it is a kind
+   of a hack, but this is the way ILINK and LINK386 work.
+
+   If file has no extension, the .obj and .o extensions are tried in turn
+   for object files, and .lib then .a are tried in turn for libraries.
+   Additionaly, for libraries we check for a file with the 'lib' prefix,
+   if one without the 'lib' prefix was not found. The '.o' and '.a'
+   extensions are tried in the last case since otherwise we can find
+   a 'something.a' when 'libsomething.lib' is available.
+*/
+
+static FILE *find_objlib (char *fullname, const char *name, int is_library)
+{
+  const char *exts [2][2] = { { ".obj", ".o" }, { ".lib", ".a" } };
+  FILE *f;
+  size_t pathlen, namelen = strlen (name);
+  char *libpath, *x;
+  int i, has_ext = 0, has_path;
+
+  /* Check if the file name has a path. If it has, we won't check the
+     LIB directories, and won't check if it has a object file extension. */
+  has_path = (strpbrk (name, ":/\\") != NULL);
+  if (has_path)
+    has_ext = 1;
+  else
+    {
+      /* Check if file has a real extension. If it is a object file it should
+         have either .o or .obj, and if it is a library it should have either
+         the .a or .lib extension. Otherwise we don't consider it a extension. */
+      x = strrchr (name, '.');
+      if (x)
+        for (i = 0; i < 2; i++)
+          if (strcmp (x, exts [is_library][i]) == 0)
             {
-              /* search thru extensions. */
-              for (i = 0; papszexts[i]; i++)
+              has_ext = 1;
+              break;
+            }
+    }
+
+  /* First loop search file name as-is, then search the paths
+     in the LIB environment variable. */
+  libpath = getenv ("LIB");
+  pathlen = 0;
+  do
+    {
+      /* Step 0: check path+filename (+'.obj/.lib' if !has_ext)
+       * Step 1: if is_library check path+'lib'+filename (+'.lib' if !has_ext)
+       * Step 2: check path+filename (+'.o/.a' if !has_ext)
+       * Step 3: if is_library check path+'lib'+filename (+'.a' if !has_ext)
+       */
+      for (i = 0; i < 4; i++)
+        {
+          char *cur = fullname + pathlen;
+
+          if ((i & 1) && !is_library)
+            continue;
+
+          if (i & 1)
+            {
+              memcpy (cur, "lib", 3);
+              cur += 3;
+            }
+
+          /* Include final zero in the case we won't append the extension */
+          memcpy (cur, name, namelen + 1);
+          cur += namelen;
+
+          if (!has_ext)
+            {
+              strcpy (cur, exts [is_library][i/2]);
+              cur = strchr (cur, 0);
+            }
+
+          f = fopen (fullname, "rb");
+          if (f)
+            {
+              if (is_library && !check_omf_library (f))
+                fclose (f);
+              else
                 {
-                  strcpy(pszfullname + cch + cchname, papszexts[i]);
-                  phFile = fopen (pszfullname, "rb");
-                  if (phFile)
-                      break;
-                  if (flibhacks)
-                    {
-                      memcpy(pszfullname + cch, "lib", 3);
-                      memcpy(pszfullname + cch + 3, pszname, cchname);
-                      strcpy(pszfullname + cch + 3 + cchname, papszexts[i]);
-                      phFile = fopen (pszfullname, "rb");
-                      if (phFile)
-                          break;
-                      memcpy(pszfullname + cch, pszname, cchname + 1);
-                    }
+                  /* Replace forward slashes with backslashes
+                     since Knut likes them :) */
+                  while ((fullname = strchr (fullname, '/')) != NULL)
+                    *fullname++ = '\\';
+                  return f;
                 }
             }
-          else
-            phFile = fopen (pszfullname, "rb");
-
-          if (!flibhacks && phFile)
-            return phFile;
-
-          if (phFile)
-            {
-              #pragma pack(1)
-              struct
-              {
-                  byte rec_type;
-                  word rec_len;
-                  dword dict_offset;
-                  word dict_blocks;
-                  byte flags;
-              } libhdr;
-              #pragma pack()
-              /* For .a libraries we will chech for a valid OMF library header. */
-              if (memicmp(pszfullname + strlen(pszfullname) - 2, ".a", 3))
-                  return phFile;
-              if (   fread(&libhdr, 1, sizeof(libhdr), phFile) == sizeof(libhdr)
-                  && libhdr.rec_type == LIBHDR
-                  && libhdr.flags <= 1 /* ASSUME only first bit is used... */
-                  && !fseek(phFile, 0, SEEK_SET)
-                  )
-                {
-                  int page_size = libhdr.rec_len + 3;
-                  if (   page_size >= 16
-                      && page_size <= 32768
-                      && !(page_size & (page_size - 1)) != 0)
-                      return phFile;
-                }
-              fclose(phFile);
-              phFile = NULL;
-            }
-        } /* foreach path in $LIB */
-    }
-  strcpy(pszfullname, pszname);
+        }
+
+      if (!libpath || has_path)
+        break;
+
+      /* Find where next LIB component ends */
+      x = strchr (libpath, ';');
+      if (!x) x = strchr (libpath, 0);
+      pathlen = x - libpath;
+
+      if (pathlen)
+        {
+          memcpy (fullname, libpath, pathlen);
+          /* Append last slash if it is not there */
+          if (fullname [pathlen - 1] != '/'
+           && fullname [pathlen - 1] != '\\')
+            fullname [pathlen++] = '\\';
+        }
+
+      /* Advance past ';' in LIB */
+      libpath = x + 1;
+    } while (*x);
+
   return NULL;
 }
-
-
-/* Wrapper around find_objlib which fixes the slashes - this looks better imho. */
-
-static FILE * find_objlib(char *pszfullname, const char *pszname, const char * const *papszexts, int flibhacks)
-{
-    FILE * phFile = find_objlib2(pszfullname, pszname, papszexts, flibhacks);
-    while ((pszfullname = strchr(pszfullname, '/')) != NULL)
-        *pszfullname++ = '\\';
-    return phFile;
-}
-
-
 
 /* Weak prelinking for Method 2 Weak support. */
@@ -674,5 +682,5 @@
       name_list *   pcur;
       FILE         *phfile;
-      char          szname[_MAX_PATH];
+      char          szname[_MAX_PATH + 1];
 
       /* definition file if any */
@@ -686,6 +694,5 @@
       for (pcur = obj_fnames; !rc && pcur; pcur = pcur->next)
         {
-          static const char * objexts[] = { ".obj", ".o", NULL };
-          phfile = find_objlib (szname, pcur->name, objexts, TRUE);
+          phfile = find_objlib (szname, pcur->name, FALSE);
           rc = WLDAddObject (pwld, phfile, szname);
         }
@@ -694,6 +701,5 @@
       for (pcur = lib_fnames; !rc && pcur; pcur = pcur->next)
         {
-          static const char * libexts[] = { ".lib", ".a", NULL };
-          phfile = find_objlib (szname, pcur->name, libexts, TRUE);
+          phfile = find_objlib (szname, pcur->name, TRUE);
           rc = WLDAddLibrary (pwld, phfile, szname);
           free(pcur->name);
@@ -895,4 +901,5 @@
   char tmp[512], *t;
   char execname[512];
+  name_list *pcur;
 
   /* Get options from response files (@filename) and wildcard (*.o) on the command. */
@@ -1116,5 +1123,15 @@
                     "*** Linker type: %s\n", linker_name, linker_type);
 
-
+  /* apply library hacks */
+  for (pcur = lib_fnames, rc = 0; !rc && pcur; pcur = pcur->next)
+    {
+      char szname[_MAX_PATH + 1];
+      FILE *phfile = find_objlib (szname, pcur->name, TRUE);
+      if (!phfile)
+        continue;
+      free (pcur->name);
+      pcur->name = xstrdup(szname);
+      fclose(phfile);
+    }
 
   /* Do the weak prelinking unless GCC_WEAKSYMS are set.
@@ -1123,21 +1140,4 @@
   if (!getenv("GCC_WEAKSYMS"))
       weak_prelink ();
-  else
-    {
-      /* apply library hacks */
-      name_list *pcur;
-      for (pcur = lib_fnames; !rc && pcur; pcur = pcur->next)
-        {
-          static const char * libexts[] = { ".lib", ".a", NULL };
-          char szname[_MAX_PATH];
-          FILE *phfile = find_objlib (szname, pcur->name, libexts, TRUE);
-          if (!phfile)
-            continue;
-          free(pcur->name);
-          pcur->name = xstrdup(szname);
-          fclose(phfile);
-        }
-
-    }
 
   /* Start building the linker command line.  We can use a response
