Index: trunk/src/emx/src/emxomf/weakld.c
===================================================================
--- trunk/src/emx/src/emxomf/weakld.c	(revision 536)
+++ trunk/src/emx/src/emxomf/weakld.c	(revision 537)
@@ -38,5 +38,5 @@
  * type groups, but the choice was made to differenciate this using flags.
  * So, symbol enumeration is done using flag masks.
- *
+ * @todo: Finish this stuff.
  *
  */
@@ -441,11 +441,23 @@
 
 
-/*******************************************************************************
-*
-*  H e l p e r s
-*  H e l p e r s
-*  H e l p e r s
-*
-*******************************************************************************/
+
+
+
+
+
+
+
+/*=============================================================================
+ *                                                                            *
+ *                                                                            *
+ *  W E A K   L I N K E R   M E T H O D S                                     *
+ *  W E A K   L I N K E R   M E T H O D S                                     *
+ *  W E A K   L I N K E R   M E T H O D S                                     *
+ *  W E A K   L I N K E R   M E T H O D S                                     *
+ *  W E A K   L I N K E R   M E T H O D S                                     *
+ *                                                                            *
+ *                                                                            *
+ *============================================================================*/
+
 
 #ifdef WLD_ENABLED_DBG
@@ -552,4 +564,16 @@
 
 
+
+/*=============================================================================
+ *                                                                            *
+ *                                                                            *
+ *  L I B R A R Y   M E T H O D S                                             *
+ *  L I B R A R Y   M E T H O D S                                             *
+ *  L I B R A R Y   M E T H O D S                                             *
+ *  L I B R A R Y   M E T H O D S                                             *
+ *  L I B R A R Y   M E T H O D S                                             *
+ *                                                                            *
+ *                                                                            *
+ *============================================================================*/
 
 
@@ -631,5 +655,5 @@
     pLib->pDict = NULL;
     return -1;
-#endif 
+#endif
 }
 
@@ -908,5 +932,5 @@
 
                 /* update statistics */
-                if (pcLoaded)   
+                if (pcLoaded)
                     (*pcLoaded)++;
 
@@ -997,6 +1021,15 @@
 
 
-
-
+/*=============================================================================
+ *                                                                            *
+ *                                                                            *
+ *  M O D U L E   M E T H O D S                                               *
+ *  M O D U L E   M E T H O D S                                               *
+ *  M O D U L E   M E T H O D S                                               *
+ *  M O D U L E   M E T H O D S                                               *
+ *  M O D U L E   M E T H O D S                                               *
+ *                                                                            *
+ *                                                                            *
+ *============================================================================*/
 
 
@@ -1107,4 +1140,83 @@
 
 
+
+
+
+
+
+
+/*=============================================================================
+ *                                                                            *
+ *                                                                            *
+ *  S Y M B O L   M E T H O D S                                               *
+ *  S Y M B O L   M E T H O D S                                               *
+ *  S Y M B O L   M E T H O D S                                               *
+ *  S Y M B O L   M E T H O D S                                               *
+ *                                                                            *
+ *                                                                            *
+ *============================================================================*/
+
+
+/**
+ * Calculate the hash value of a symbol.
+ * @returns hash value.
+ * @param   pszSym  Symbol to calculate it for.
+ * @param   cch     Symbol length.
+ * @todo    This ain't respecting case sensitivity.
+ */
+static inline unsigned symHash(const char* pszSym, unsigned cch)
+{
+    unsigned uHash = 0;
+    while (     cch
+           &&   (pszSym[0] != '$' || pszSym[1] != 'w' || pszSym[2] != '$')
+             )
+    {
+        uHash = uHash * 63377 + *pszSym;
+        pszSym++;
+        cch--;
+    }
+    uHash %= WLDSYM_HASH_SIZE;
+    return uHash;
+}
+
+/**
+ * Find the symbol by the name pszName.
+ * @returns Pointer to matching symbol.
+ * @returns NULL if not found.
+ * @param   pWld    Linker Instance.
+ * @param   pszName Name of the symbol to find.
+ */
+static PWLDSYM      symLookup(PWLD pWld, const char *pszName)
+{
+    PWLDSYM     pSym;
+    const char *psz;
+    unsigned    cchName;
+    unsigned    uHash;
+
+    /*
+     * Calculate the hash of the symbol
+     *
+     * It's easier just to add it to the string table than starting to
+     * check the correct case function and such. As there is a good
+     * likelyhood that the symbol exists there is little expense in doing
+     * this compared to the convenience. If it's slow we'll optimize grow.c
+     * (if possible) and gain everywhere.
+     */
+    psz = strstr(pszName, "$w$");
+    cchName = psz ? psz - pszName : strlen(pszName);
+    pszName = (pWld->fFlags & WLDC_CASE_INSENSITIVE ? strpool_addnu : strpool_addn)(pWld->pStrMisc, pszName, cchName);
+    uHash = symHash(pszName, cchName);
+
+    /* look it up */
+    for (pSym = pWld->Global.ap[uHash]; pSym; pSym = pSym->pHashNext)
+       if (pSym->pszName == pszName)
+           return pSym;
+
+    return NULL;
+}
+
+
+
+
 /**
  * Symbol enumerator.
@@ -1322,26 +1434,4 @@
 #endif
 
-
-/**
- * Calculate the hash value of a symbol.
- * @returns hash value.
- * @param   pszSym  Symbol to calculate it for.
- * @param   cch     Symbol length.
- * @todo    This ain't respecting case sensitivity.
- */
-static inline unsigned symHash(const char* pszSym, unsigned cch)
-{
-    unsigned uHash = 0;
-    while (     cch
-           &&   (pszSym[0] != '$' || pszSym[1] != 'w' || pszSym[2] != '$')
-             )
-    {
-        uHash = uHash * 65599 + *pszSym;
-        pszSym++;
-        cch--;
-    }
-    uHash %= WLDSYM_HASH_SIZE;
-    return uHash;
-}
 
 /**
@@ -1465,5 +1555,5 @@
         if ( (     /* 1 */
                 (fFlags & WLDSF_TYPEMASK) == WLDSF_UNDEF
-             && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_COMM 
+             && ((pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_PUBLIC || (pSym->fFlags & WLDSF_TYPEMASK) == WLDSF_COMM
                  || (pSym->fFlags & (WLDSF_TYPEMASK | WLDSF_WEAK)) == WLDSF_UNDEF || (pSym->fFlags & (WLDSF_TYPEMASK)) == WLDSF_IMPORT)
             ) || ( /* 2 */
@@ -1929,4 +2019,27 @@
 }
 
+
+
+
+
+
+
+
+
+
+
+/*=============================================================================
+ *                                                                            *
+ *                                                                            *
+ *  M I S C   M E T H O D S                                                   *
+ *  M I S C   M E T H O D S                                                   *
+ *  M I S C   M E T H O D S                                                   *
+ *  M I S C   M E T H O D S                                                   *
+ *  M I S C   M E T H O D S                                                   *
+ *                                                                            *
+ *                                                                            *
+ *============================================================================*/
+
+
 /**
  * Reads an OMF module from a file.
@@ -2290,14 +2403,21 @@
 
 
-/*******************************************************************************
-*
-*  P u b l i c   I n t e r f a c e
-*  P u b l i c   I n t e r f a c e
-*  P u b l i c   I n t e r f a c e
-*
-*******************************************************************************/
-
-
-
+
+
+
+
+
+
+/*=============================================================================
+ *                                                                            *
+ *                                                                            *
+ *  P U B L I C   M E T H O D S                                               *
+ *  P U B L I C   M E T H O D S                                               *
+ *  P U B L I C   M E T H O D S                                               *
+ *  P U B L I C   M E T H O D S                                               *
+ *  P U B L I C   M E T H O D S                                               *
+ *                                                                            *
+ *                                                                            *
+ *============================================================================*/
 
 /**
@@ -2344,5 +2464,5 @@
     for (pObj = pWld->pObjs; pObj;)
     {
-        void *pv = pObj;   
+        void *pv = pObj;
         modClose(pObj);
         pObj = pObj->pNext;
@@ -2351,5 +2471,5 @@
     for (pObj = pWld->pDef; pObj;)
     {
-        void *pv = pObj;   
+        void *pv = pObj;
         modClose(pObj);
         pObj = pObj->pNext;
@@ -2360,5 +2480,5 @@
     for (pLib = pWld->pLibs; pLib;)
     {
-        void *pv = pLib;   
+        void *pv = pLib;
         libClose(pLib);
         pLib = pLib->pNext;
@@ -2836,4 +2956,16 @@
 
 
+/** Parameter structure for wlddefCallback (module definition parser callback). */
+typedef struct wlddefCallback_param
+{
+    /** Linker Instance. */
+    PWLD        pWld;
+    /** Read file stream of the current definition file. */
+    FILE       *phOrgFile;
+    /** Write file stream of the new, modified, defintion file. */
+    FILE       *phNewFile;
+    /** Our current linenumber index. */
+    unsigned    iLine;
+} WLDDCPARAM, *PWLDDCPARAM;
 
 /**
@@ -2845,14 +2977,20 @@
  * @param   pStmt   Statement we're processing.
  * @param   eToken  Token we're processing.
- * @param   pvArg   Pointer to file stream for the output file.
- *                  
- */
-static int wldDefCallbackGenerateWeakAliases(struct _md *pMD, const _md_stmt *pStmt, _md_token eToken, void *pvArg)
-{
-    unsigned        fFlags;
-    unsigned        uOrdinal;
-    unsigned        cWords;
-    PWLDSYM         pSym;
-    FILE *          phFile = (PHFILE)pvArg;
+ * @param   pvArg   Pointer to a WLDDCPARAM structure.
+ * @sketch
+ *
+ *  If it exports a weak symbol Then
+ *      While linenumber(_md) > linenumber phOrgFile
+ *          Copy line from phOrgFile to phNewFile
+ *      Write modifed line to phNewFile and
+ *      Skip a line in phOrgFile.
+ *  Endif
+ *
+ *  The caller of _md_parse will make sure the last chunk of the file is
+ *  copied to the new file.
+ */
+static int wlddefCallback(struct _md *pMD, const _md_stmt *pStmt, _md_token eToken, void *pvArg)
+{
+    PWLDDCPARAM     pParam = (PWLDDCPARAM)pvArg;
 
     switch (eToken)
@@ -2862,28 +3000,63 @@
          */
         case _MD_EXPORTS:
-            fFlags = uOrdinal = cWords = 0;
+        {
+            char        szTmp[1024];
+            int         cch;
+            unsigned    iMDLine;
+            PWLDSYM     pSymInt = NULL;
+            PWLDSYM     pSymExp;
+
+            pSymExp = symLookup(pParam->pWld, pStmt->export.entryname);
+            if (pStmt->export.internalname[0])
+                pSymInt = symLookup(pParam->pWld, pStmt->export.internalname);
+            if (!pSymExp && !pSymInt)
+            {
+                wldWarn(pParam->pWld, "Failed to find exported symbols! (%s, %s, %d)",
+                        pStmt->export.entryname, pStmt->export.internalname, pStmt->export.ordinal);
+                return 0;               /* .ignore it. good idea? */
+            }
+
+            /* Skip it all if neither of the symbols are weak. */
+            if (    !(pSymExp->fFlags & WLDSF_WEAK)
+                &&   (!pSymInt  || !(pSymInt->fFlags & WLDSF_WEAK)))
+                return 0;
+
+            /* Copy line from org to new so we're up to date. */
+            iMDLine = _md_get_linenumber(pMD);
+            while (pParam->iLine < iMDLine)
+            {
+                if (!fgets(szTmp, 512 /* this is the size _md_* uses */, pParam->phOrgFile))
+                {
+                    wldErr(pParam->pWld, "Read error while reading original .def file.");
+                    strcpy(szTmp, ";read error");
+                }
+
+                if (++pParam->iLine >= iMDLine) /* skip last line. */
+                    break;
+                if (fputs(szTmp, pParam->phNewFile) < 0)
+                    return wldErr(pParam->pWld, "Write error.");
+            }
+
+            /* if the internal symbol is weak, replace it with the right $w$. */
+            if (pSymInt && (pSymInt->fFlags & WLDSF_WEAK))
+                cch = sprintf(szTmp, "  \"%s\" = \"%s\"", pStmt->export.entryname, pSymInt->pszWeakName);
+            else
+                cch = sprintf(szTmp, "  \"%s\" = \"%s\"", pStmt->export.entryname, pSymExp->pszWeakName);
             if (pStmt->export.flags & _MDEP_ORDINAL)
-                uOrdinal = pStmt->export.ordinal;
+                cch += sprintf(&szTmp[cch], " @%d", pStmt->export.ordinal);
             if (pStmt->export.flags & _MDEP_RESIDENTNAME)
-                fFlags |= WLDSEF_NONRESIDENT;
-            else if (pStmt->export.flags & _MDEP_NONAME)
-                fFlags |= WLDSEF_NONAME;
-            else
-                fFlags |= WLDSEF_DEFAULT;
+                cch += sprintf(&szTmp[cch], " RESIDENTNAME");
+            if (pStmt->export.flags & _MDEP_NONAME)
+                cch += sprintf(&szTmp[cch], " NONAME");
             if (pStmt->export.flags & _MDEP_NODATA)
-                fFlags |= WLDSEF_NODATA;
+                cch += sprintf(&szTmp[cch], " NODATA");
             if (pStmt->export.flags & _MDEP_PWORDS)
-                cWords = pStmt->export.pwords;
-            pSym = symAddExport(pParam->pWld, pParam->pMod, 0,
-                                fFlags, cWords,
-                                pStmt->export.entryname, -1,
-                                pStmt->export.internalname, -1,
-                                uOrdinal);
-            if (!pSym)
-            {
-                pParam->rc = -4;
-                return -4;
-            }
+                cch += sprintf(&szTmp[cch], " %d", pStmt->export.pwords);
+            cch += sprintf(&szTmp[cch], "   ; !weakld changed this!\n");
+
+            if (fputs(szTmp, pParam->phNewFile) < 0)
+                return wldErr(pParam->pWld, "Write error.");
             break;
+        }
 
         /*
@@ -2891,7 +3064,6 @@
          */
         case _MD_parseerror:
-            wldErr(pWld, "Parse error %d on line %d. (errorcode=%d stmt=%d)",
+            wldErr(pParam->pWld, "Parse error %d on line %d. (errorcode=%d stmt=%d)",
                    _md_get_linenumber(pMD), pStmt->error.code, pStmt->error.stmt);
-            pParam->rc = -2;
             break;
 
@@ -2900,5 +3072,4 @@
          */
         default:
-            pMD->
             break;
     }
@@ -2935,5 +3106,5 @@
         sprintf(pszFile, "%s\\%s%x%lx%d%lx%s", pszTmp, pszPrefix, pid, tv.tv_sec, c, tv.tv_usec, pszSuffix);
     } while (!stat(pszFile, &s));
-    
+
     return 0;
 }
@@ -2956,5 +3127,4 @@
 int     wldGenerateWeakAliases(PWLD pWld, char *pszObjName, char *pszDefName)
 {
-    char *      psz;
     FILE *      phFile;
     int         rc;
@@ -2965,5 +3135,7 @@
         *pszDefName = '\0';
 
-    /* generate the object  file */
+    /*
+     * Generate the object file
+     */
     rc = wldTempFile(pWld, pszObjName, "wk", ".obj");
     if (rc)
@@ -2993,5 +3165,5 @@
         omf.ach[1+cch] = 0;         /* crc */
         fwrite(&omf, omf.hdr.cb + sizeof(OMFREC), 1, phFile);
-        /* todo: check if we'll need more shit here to satisfy the linkers */
+        /* todo: link386 doesn't like if there are too many alias in one module btw. */
 
 
@@ -3033,6 +3205,11 @@
     }
 
-    /* do the definition file */
-    if (!rc && pWld->pDef && pszDefName)
+
+    /*
+     * Do the definition file.
+     *      We don't need to do this if the above code failed or
+     *      didn't issue any aliases.
+     */
+    if (!rc && pWld->pDef && pszDefName && pszObjName[0])
     {
         rc = wldTempFile(pWld, pszDefName, "wk", ".def");
@@ -3041,22 +3218,35 @@
             WLDINFO(pWld, ("Generating definition file '%s' for weak exports.", pszDefName));
 
-            /* open it */
+            /* open output file */
             phFile = fopen(pszDefName, "w");
             if (phFile)
             {
-                FILE *phOrgDef = fopen(pWld->pDef->pszModName, "r");
-                if (phOrgDef)
+                /* open original file */
+                FILE *phOrgFile = fopen(pWld->pDef->pszModName, "r");
+                if (phOrgFile)
                 {
-                    char *pachOrgDef = fsize
-                    struct _md *pMD;
-
-                    /* open original def file */
-                    pMD = _md_open(pWld->pDef->pszModName);
+                    /* open original def file with the ModDef library.  */
+                    struct _md *pMD = _md_open(pWld->pDef->pszModName);
                     if (pMD)
                     {
+                        WLDDCPARAM  param;
+                        param.pWld = pWld;
+                        param.phOrgFile = phOrgFile;
+                        param.phNewFile = phFile;
+                        param.iLine = 0;
+
                         /* parse it */
                         _md_next_token(pMD);
-                        rc = _md_parse(pMD, wldDefCallbackGenerateWeakAliases, phFile);
+                        rc = _md_parse(pMD, wlddefCallback, &param);
                         _md_close(pMD);
+
+                        /* copy the rest of the file */
+                        if (!rc)
+                        {
+                            char szTmp[512];
+                            while (fgets(szTmp, sizeof(szTmp), phOrgFile))
+                                if (fputs(szTmp, phFile) < 0)
+                                    rc = wldErr(pWld, "Write error.");
+                        }
                     }
                     else
@@ -3065,5 +3255,5 @@
                 }
                 else
-                    rc = wldErr(pWld, "Failed to open '%s' for reading.\n", pszDefName);
+                    rc = wldErr(pWld, "Failed to open '%s' for reading.\n", pWld->pDef->pszModName);
                 fclose(phFile);
             }
