Index: /trunk/ChangeLog
===================================================================
--- /trunk/ChangeLog	(revision 331)
+++ /trunk/ChangeLog	(revision 332)
@@ -1,3 +1,7 @@
 /* $Id$ */
+
+2005-10-30: bird
+    - kBuild/bin/amd64.linux/kDepPre, src/kDepPre/kDepPre.c:
+        o Fix case option - need it on unix for cl.exe with wine.
 
 2005-10-29: bird
Index: /trunk/src/kDepPre/kDepPre.c
===================================================================
--- /trunk/src/kDepPre/kDepPre.c	(revision 331)
+++ /trunk/src/kDepPre/kDepPre.c	(revision 332)
@@ -29,8 +29,13 @@
 #include <stdlib.h>
 #include <string.h>
+#include <errno.h>
 #include <ctype.h>
+#include <sys/stat.h>
 #ifdef __WIN32__
 #include <windows.h>
 #endif
+#if !defined(__WIN32__) && !defined(__OS2__)
+# include <dirent.h>
+#endif 
 
 #ifdef HAVE_FGETC_UNLOCKED
@@ -69,4 +74,6 @@
 /** List of dependencies. */
 static PDEP g_pDeps = NULL;
+/** Whether or not to fixup win32 casing. */
+static int  g_fFixCase = 0;
 
 
@@ -79,5 +86,5 @@
  *                      The buffer must be able to hold one more byte than the string length.
  */
-void w32_fixcase(char *pszPath)
+void fixcase(char *pszPath)
 {
 #define my_assert(expr) \
@@ -189,5 +196,116 @@
 }
 
+/**
+ * Corrects all slashes to unix slashes.
+ * 
+ * @returns pszFilename.
+ * @param   pszFilename     The filename to correct.
+ */
+char *fixslash(char *pszFilename)
+{
+    char *psz = pszFilename;
+    while ((psz = strchr(psz, '\\')) != NULL)
+        *psz++ = '/';
+    return pszFilename;
+}
+
+#elif defined(__OS2__)
+
+/**
+ * Corrects the case of a path.
+ *
+ * @param   pszPath     Pointer to the path, both input and output.
+ *                      The buffer must be able to hold one more byte than the string length.
+ */
+void fixcase(char *pszFilename)
+{
+    return;
+}
+
+#else
+
+/**
+ * Corrects the case of a path.
+ *
+ * @param   pszPath     Pointer to the path, both input and output.
+ */
+void fixcase(char *pszFilename)
+{
+    char *psz;
+
+    /*
+     * Skip the root.
+     */
+    psz = pszFilename;
+    while (*psz == '/')
+        psz++;
+
+    /*
+     * Iterate all the components.
+     */
+    while (*psz)
+    {
+        char  chSlash;
+        struct stat s;
+        char   *pszStart = psz;
+
+        /*
+         * Find the next slash (or end of string) and terminate the string there.
+         */
+        while (*psz != '/' && *psz)
+            *psz++;
+        chSlash = *psz;
+        *psz = '\0';
+
+        /*
+         * Does this part exist?
+         * If not we'll enumerate the directory and search for an case-insensitive match.
+         */
+        if (stat(pszFilename, &s))
+        {
+            struct dirent  *pEntry;
+            DIR            *pDir;
+            if (pszStart == pszFilename)
+                pDir = opendir(*pszFilename ? pszFilename : ".");
+            else
+            {
+                pszStart[-1] = '\0';
+                pDir = opendir(pszFilename);
+                pszStart[-1] = '/';
+            }
+            if (!pDir)
+            {
+                *psz = chSlash;
+                break; /* giving up, if we fail to open the directory. */
+            }
+
+            while ((pEntry = readdir(pDir)) != NULL)
+            {
+                if (!strcasecmp(pEntry->d_name, pszStart))
+                {
+                    strcpy(pszStart, pEntry->d_name);
+                    break;
+                }
+            }
+            closedir(pDir);
+            if (!pEntry)
+            {
+                *psz = chSlash;
+                break;  /* giving up if not found. */
+            }
+        }
+
+        /* restore the slash and press on. */
+        *psz = chSlash;
+        while (*psz == '/')
+            psz++;
+    }
+
+    return;
+}
+
+
 #endif
+
 
 
@@ -203,4 +321,13 @@
     for (pDep = g_pDeps; pDep; pDep = pDep->pNext)
     {
+        struct stat s;
+#ifdef __WIN32__
+        char    szFilename[_MAX_PATH + 1];
+#else
+        char    szFilename[PATH_MAX + 1];
+#endif 
+        char   *pszFilename;
+        char   *psz;
+
         /*
          * Skip some fictive names like <built-in> and <command line>.
@@ -209,31 +336,42 @@
             &&  pDep->szFilename[pDep->cchFilename - 1] == '>')
             continue;
-
-#if defined(__WIN32__)
-        {
-            char *psz;
-            char szFilename[_MAX_PATH + 1];
-            if (_fullpath(szFilename, pDep->szFilename, sizeof(szFilename)))
-                w32_fixcase(szFilename);
-            psz = szFilename;
-            while ((psz = strchr(psz, '\\')) != NULL)
-                *psz++ = '/';
-            fprintf(pOutput, " \\\n\t%s", szFilename);
-        }
-
-#elif !defined(__OS2__)
-        {
-            const char *psz = strchr(pDep->szFilename, ':');
-            if (psz)
-                fprintf(pOutput, " \\\n\t%s", psz + 1);
+        pszFilename = pDep->szFilename;
+
+#if !defined(__OS2__) && !defined(__WIN32__)
+        /*
+         * Skip any drive letters from compilers running in wine.
+         */
+        if (pszFilename[1] == ':')
+            pszFilename += 2;
+#endif 
+
+        /*
+         * The microsoft compilers are notoriously screwing up the casing.
+         * This will screw with kmk (/ GNU Make) on case sensitive systems, it 
+         * may even do so on win32...
+         */
+        if (g_fFixCase)
+        {
+#ifdef __WIN32__
+            if (_fullpath(szFilename, pszFilename, sizeof(szFilename)))
+                fixslash(szFilename);
             else
-                fprintf(pOutput, " \\\n\t%s", pDep->szFilename);
-        }
-
-#else /* __OS2__ */
-        fprintf(pOutput, " \\\n\t%s", pDep->szFilename);
-
-#endif /* __OS2__ */
-    }
+#endif
+                strcpy(szFilename, pszFilename);
+            fixcase(szFilename);
+            pszFilename = szFilename;
+        }
+
+        /*
+         * Check that the file exists before we start depending on it.
+         */
+        if (stat(pszFilename, &s))
+        {
+            fprintf(stderr, "kDepPre: Skipping '%s' - %s!\n", szFilename, strerror(errno));
+            continue;
+        }
+
+        fprintf(pOutput, " \\\n\t%s", pszFilename);
+    } /* foreach dependency */
     fprintf(pOutput, "\n\n");
 }
@@ -476,5 +614,5 @@
 static void usage(const char *argv0)
 {
-    printf("syntax: %s [-l=c] -o <output> -t <target> < - | <filename> | -e <cmdline> >\n", argv0);
+    printf("syntax: %s [-l=c] -o <output> -t <target> [-f] < - | <filename> | -e <cmdline> >\n", argv0);
 }
 
@@ -526,5 +664,8 @@
                         pszOutput = argv[i];
                     }
-                    pOutput = fopen(pszOutput, "w");
+                    if (pszOutput[0] == '-' && !pszOutput[1])
+                        pOutput = stdout;
+                    else
+                        pOutput = fopen(pszOutput, "w");
                     if (!pOutput)
                     {
@@ -591,5 +732,4 @@
                 }
 
-
                 /*
                  * Pipe input.
@@ -599,4 +739,13 @@
                     pInput = stdin;
                     fInput = 1;
+                    break;
+                }
+
+                /*
+                 * Fix case.
+                 */
+                case 'f':
+                {
+                    g_fFixCase = 1;
                     break;
                 }
