Index: trunk/src/kmk/kmkbuiltin/md5sum.c
===================================================================
--- trunk/src/kmk/kmkbuiltin/md5sum.c	(revision 3129)
+++ trunk/src/kmk/kmkbuiltin/md5sum.c	(revision 3131)
@@ -41,4 +41,5 @@
 #include "kmkbuiltin.h"
 #include "../../lib/md5.h"
+#include <k/kTypes.h>
 
 /*#define MD5SUM_USE_STDIO*/
@@ -61,4 +62,5 @@
             " -b, --binary      Read files in binary mode. (default)\n"
             " -t, --text        Read files in text mode.\n"
+            " -m, --manifest    Output in kBuild fetch 'manifest' format.\n"
             " -p, --progress    Show progress indicator on large files.\n"
             " -o, --output      Name of the output list file. Useful with -p.\n"
@@ -262,5 +264,5 @@
  * @param   pvFile          The opaque pointer returned by open_file
  */
-static double size_file(void *pvFile)
+static KU64 size_file(void *pvFile)
 {
 #if defined(_MSC_VER)
@@ -272,5 +274,5 @@
 # endif
     if (cb >= 0)
-        return (double)cb;
+        return cb;
 
 #elif defined(MD5SUM_USE_STDIO)
@@ -295,6 +297,7 @@
  * @param   pDigest     Where to store the MD5 digest.
  * @param   fProgress   Whether to show a progress bar.
- */
-static int calc_md5sum(void *pvFile, unsigned char pDigest[16], unsigned fProgress)
+ * @param   pcbFile     Where to return the file size. Optional.
+ */
+static int calc_md5sum(void *pvFile, unsigned char pDigest[16], unsigned fProgress, KU64 *pcbFile)
 {
     int cb;
@@ -302,6 +305,6 @@
     struct MD5Context Ctx;
     unsigned uPercent = 0;
-    double off = 0.0;
-    double cbFile = size_file(pvFile);
+    KU64 off = 0;
+    KU64 const cbFile = size_file(pvFile);
 
     /* Get a decent sized buffer assuming we'll be spending more time reading
@@ -346,4 +349,5 @@
             break;
         }
+        off += cb;
 
         /* update the progress indicator. */
@@ -351,6 +355,5 @@
         {
             unsigned uNewPercent;
-            off += cb;
-            uNewPercent = (unsigned)((off / cbFile) * 100);
+            uNewPercent = (unsigned)(((double)off / cbFile) * 100);
             if (uNewPercent != uPercent)
             {
@@ -365,4 +368,7 @@
     MD5Final(pDigest, &Ctx);
 
+    if (pcbFile)
+        *pcbFile = off;
+
     if (fProgress)
         printf("\b\b\b\b    \b\b\b\b");
@@ -386,5 +392,5 @@
     int rc;
 
-    rc = calc_md5sum(pvFile, DigestFile, fProgress);
+    rc = calc_md5sum(pvFile, DigestFile, fProgress, NULL);
     if (!rc)
         rc = memcmp(Digest, DigestFile, 16) ? -1 : 0;
@@ -583,8 +589,10 @@
  * @param   fText           The mode to open the file in.
  * @param   fQuiet          Whether to be quiet or verbose about errors.
+ * @param   fManifest       Whether to format the output like a fetch manifest.
  * @param   fProgress       Whether to show an progress indicator on large files.
  * @param   pOutput         Where to write the list. Progress is always written to stdout.
  */
-static int md5sum_file(const char *pszFilename, unsigned fText, unsigned fQuiet, unsigned fProgress, FILE *pOutput)
+static int md5sum_file(const char *pszFilename, unsigned fText, unsigned fQuiet, unsigned fProgress,
+                       unsigned fManifest, FILE *pOutput)
 {
     int rc;
@@ -598,9 +606,10 @@
     {
         unsigned char Digest[16];
+        KU64 cbFile = 0;
 
         if (fProgress && pOutput)
             fprintf(stdout, "%s: ", pszFilename);
 
-        rc = calc_md5sum(pvFile, Digest, fProgress);
+        rc = calc_md5sum(pvFile, Digest, fProgress, &cbFile);
         close_file(pvFile);
 
@@ -616,10 +625,18 @@
             char szDigest[36];
             digest_to_string(Digest, szDigest);
+            if (!fManifest)
+            {
+                if (pOutput)
+                    fprintf(pOutput, "%s %s%s\n", szDigest, fText ? "" : "*", pszFilename);
+                fprintf(stdout, "%s %s%s\n", szDigest, fText ? "" : "*", pszFilename);
+            }
+            else
+            {
+                if (pOutput)
+                    fprintf(pOutput, "%s_SIZE := %" KU64_PRI "\n%s_MD5  := %s\n", pszFilename, cbFile, pszFilename, szDigest);
+                fprintf(stdout, "%s_SIZE := %" KU64_PRI "\n%s_MD5  := %s\n", pszFilename, cbFile, pszFilename, szDigest);
+            }
             if (pOutput)
-            {
-                fprintf(pOutput, "%s %s%s\n", szDigest, fText ? "" : "*", pszFilename);
                 fflush(pOutput);
-            }
-            fprintf(stdout, "%s %s%s\n", szDigest, fText ? "" : "*", pszFilename);
             fflush(stdout);
         }
@@ -654,4 +671,5 @@
     int fQuiet = 0;
     int fChecking = 0;
+    int fManifest  = 0;
     int fProgress = 0;
     int fNoMoreOptions = 0;
@@ -691,4 +709,6 @@
                 else if (!strcmp(psz, "-check-file"))
                     psz = "C";
+                else if (!strcmp(psz, "-manifest"))
+                    psz = "m";
                 else if (!strcmp(psz, "-output"))
                     psz = "o";
@@ -722,4 +742,8 @@
                         fText = 1;
                         fBinaryTextOpt = 1;
+                        break;
+
+                    case 'm':
+                        fManifest = 1;
                         break;
 
@@ -822,5 +846,5 @@
             }
 
-            rc |= md5sum_file(argv[i], fText, fQuiet, fProgress && !fQuiet, pOutput);
+            rc |= md5sum_file(argv[i], fText, fQuiet, fProgress && !fQuiet && !fManifest, fManifest, pOutput);
         }
         i++;
