Changeset 2263 for trunk/src


Ignore:
Timestamp:
Jan 23, 2009, 1:22:47 AM (16 years ago)
Author:
bird
Message:

kDepObj: Initial code that deals with Watcom and MASM OMF files.

Location:
trunk/src
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kmk/Makefile.am

    r2249 r2263  
    6969                kmkbuiltin/install.c \
    7070                kmkbuiltin/kDepIDB.c \
     71                kmkbuiltin/kDepObj.c \
    7172                kmkbuiltin/ln.c \
    7273                kmkbuiltin/md5sum.c \
  • trunk/src/kmk/Makefile.kmk

    r2243 r2263  
    240240        kmkbuiltin/install.c \
    241241        kmkbuiltin/kDepIDB.c \
     242        kmkbuiltin/kDepObj.c \
    242243        kmkbuiltin/md5sum.c \
    243244        kmkbuiltin/mkdir.c \
     
    281282        kmk_test \
    282283        kDepIDB \
     284        kDepObj \
    283285
    284286kmk_append_TEMPLATE = BIN-KMK
     
    383385kDepIDB_SOURCES = \
    384386        kmkbuiltin/kDepIDB.c
     387
     388kDepObj_TEMPLATE = BIN-KMK
     389kDepObj_DEFS = kmk_builtin_kDepObj=main
     390kDepObj_INCS = .
     391kDepObj_LIBS = $(LIB_KDEP)
     392kDepObj_SOURCES = \
     393        kmkbuiltin/kDepObj.c
    385394
    386395
  • trunk/src/kmk/kmkbuiltin.c

    r2243 r2263  
    211211        rc = kmk_builtin_test(argc, argv, environ, ppapszArgvToSpawn);
    212212    /* rarely used commands: */
     213    else if (!strcmp(pszCmd, "kDepObj"))
     214        rc = kmk_builtin_kDepObj(argc, argv, environ);
    213215    else if (!strcmp(pszCmd, "chmod"))
    214216        rc = kmk_builtin_chmod(argc, argv, environ);
  • trunk/src/kmk/kmkbuiltin.h

    r2243 r2263  
    5353extern int kmk_builtin_test(int argc, char **argv, char **envp, char ***ppapszArgvSpawn);
    5454extern int kmk_builtin_kDepIDB(int argc, char **argv, char **envp);
     55extern int kmk_builtin_kDepObj(int argc, char **argv, char **envp);
    5556
    5657extern char *kmk_builtin_func_printf(char *o, char **argv, const char *funcname);
  • trunk/src/kmk/kmkbuiltin/kDepIDB.c

    r2243 r2263  
    3838#endif
    3939#if !defined(_MSC_VER)
    40 # include <stdint.h>
    4140# include <unistd.h>
    4241#else
    43 # define USE_WIN_MMAP
    4442# include <io.h>
    45 # include <Windows.h>
    46  typedef unsigned char  uint8_t;
    47  typedef unsigned short uint16_t;
    48  typedef unsigned int   uint32_t;
    4943#endif
    50 /*#include "kDep.h"*/
     44#include "../../lib/k/kDefs.h"
     45#include "../../lib/k/kTypes.h"
    5146#include "../../lib/kDep.h"
    5247#include "kmkbuiltin.h"
    5348
    54 #define OFFSETOF(type, member)  ( (int)(size_t)(void *)&( ((type *)(void *)0)->member) )
    55 
     49
     50/*******************************************************************************
     51*   Defined Constants And Macros                                               *
     52*******************************************************************************/
    5653/*#define DEBUG*/
    5754#ifdef DEBUG
    5855# define dprintf(a)             printf a
    59 # define dump(pb, cb, offBase)  hexdump(pb,cb,offBase)
     56# define dump(pb, cb, offBase)  depHexDump(pb,cb,offBase)
    6057#else
    6158# define dprintf(a)             do {} while (0)
     
    7067static const char *argv0 = "";
    7168
    72 #ifdef DEBUG
    73 /**
    74  * Performs a hexdump.
    75  */
    76 static void hexdump(const uint8_t *pb, size_t cb, size_t offBase)
    77 {
    78     static const char   szHex[16] = "0123456789abcdef";
    79 
    80     const unsigned      cchWidth = 16;
    81     size_t              off = 0;
    82     while (off < cb)
    83     {
    84         unsigned i;
    85         printf("%s%0*x %04x:", off ? "\n" : "", sizeof(pb) * 2, offBase + off, off);
    86         for (i = 0; i < cchWidth && off + i < cb ; i++)
    87             printf(off + i < cb ? !(i & 7) && i ? "-%02x" : " %02x" : "   ", pb[i]);
    88 
    89         while (i++ < cchWidth)
    90                 printf("   ");
    91         printf(" ");
    92 
    93         for (i = 0; i < cchWidth && off + i < cb; i++)
    94         {
    95             const uint8_t u8 = pb[i];
    96             printf("%c", u8 < 127 && u8 >= 32 ? u8 : '.', 1);
    97         }
    98         off += cchWidth;
    99         pb  += cchWidth;
    100     }
    101     printf("\n");
    102 }
    103 #endif
    10469
    10570/**
     
    11378 * @param   cchPrefix       The size of the prefix.
    11479 */
    115 static int ScanStream(uint8_t *pbStream, size_t cbStream, const char *pszPrefix, size_t cchPrefix)
    116 {
    117     const uint8_t  *pbCur = pbStream;
     80static int ScanStream(KU8 *pbStream, size_t cbStream, const char *pszPrefix, size_t cchPrefix)
     81{
     82    const KU8      *pbCur = pbStream;
    11883    size_t          cbLeft = cbStream;
    11984    register char   chFirst = *pszPrefix;
     
    140105
    141106    return 0;
    142 }
    143 
    144 
    145 #ifdef USE_WIN_MMAP
    146 /** Handle to the current file mapping object. */
    147 static HANDLE g_hMapObj = NULL;
    148 #endif
    149 
    150 
    151 /**
    152  * Reads the file specified by the pInput file stream into memory.
    153  * The size of the file is returned in *pcbFile if specified.
    154  * The returned pointer should be freed by FreeFileMemory().
    155  */
    156 void *ReadFileIntoMemory(FILE *pInput, size_t *pcbFile)
    157 {
    158     void       *pvFile;
    159     long        cbFile;
    160 
    161     /*
    162      * Figure out file size.
    163      */
    164 #if defined(_MSC_VER)
    165     cbFile = _filelength(fileno(pInput));
    166     if (cbFile < 0)
    167 #else
    168     if (    fseek(pInput, 0, SEEK_END) < 0
    169         ||  (cbFile = ftell(pInput)) < 0
    170         ||  fseek(pInput, 0, SEEK_SET))
    171 #endif
    172     {
    173         fprintf(stderr, "%s: error: Failed to determin file size.\n", argv0);
    174         return NULL;
    175     }
    176     if (pcbFile)
    177         *pcbFile = cbFile;
    178 
    179     /*
    180      * Try mmap first.
    181      */
    182 #ifdef USE_WIN_MMAP
    183     {
    184         HANDLE hMapObj = CreateFileMapping((HANDLE)_get_osfhandle(fileno(pInput)),
    185                                            NULL, PAGE_READONLY, 0, cbFile, NULL);
    186         if (hMapObj != NULL)
    187         {
    188             pvFile = MapViewOfFile(hMapObj, FILE_MAP_READ, 0, 0, cbFile);
    189             if (pvFile)
    190             {
    191                 g_hMapObj = hMapObj;
    192                 return pvFile;
    193             }
    194             fprintf(stderr, "%s: warning: MapViewOfFile failed, %d.\n", argv0, GetLastError());
    195             CloseHandle(hMapObj);
    196         }
    197         else
    198             fprintf(stderr, "%s: warning: CreateFileMapping failed, %d.\n", argv0, GetLastError());
    199     }
    200 
    201 #endif
    202 
    203     /*
    204      * Allocate memory and read the file.
    205      */
    206     pvFile = malloc(cbFile + 1);
    207     if (pvFile)
    208     {
    209         if (fread(pvFile, cbFile, 1, pInput))
    210         {
    211             ((uint8_t *)pvFile)[cbFile] = '\0';
    212             return pvFile;
    213         }
    214         fprintf(stderr, "%s: error: Failed to read %ld bytes.\n", argv0, cbFile);
    215         free(pvFile);
    216     }
    217     else
    218         fprintf(stderr, "%s: error: Failed to allocate %ld bytes (file mapping).\n", argv0, cbFile);
    219     return NULL;
    220 }
    221 
    222 
    223 static void FreeFileMemory(void *pvFile)
    224 {
    225 #if defined(USE_WIN_MMAP)
    226     if (g_hMapObj)
    227     {
    228         UnmapViewOfFile(pvFile);
    229         CloseHandle(g_hMapObj);
    230         return;
    231     }
    232 #endif
    233     free(pvFile);
    234107}
    235108
     
    244117
    245118/** A PDB 7.0 Page number. */
    246 typedef uint32_t PDB70PAGE;
     119typedef KU32 PDB70PAGE;
    247120/** Pointer to a PDB 7.0 Page number. */
    248121typedef PDB70PAGE *PPDB70PAGE;
     
    254127{
    255128    /** The size of the stream. */
    256     uint32_t    cbStream;
     129    KU32        cbStream;
    257130} PDB70STREAM, *PPDB70STREAM;
    258131
     
    266139{
    267140    /** The signature string. */
    268     uint8_t     szSignature[sizeof(PDB_SIGNATURE_700)];
     141    KU8         szSignature[sizeof(PDB_SIGNATURE_700)];
    269142    /** The page size. */
    270     uint32_t    cbPage;
     143    KU32        cbPage;
    271144    /** The start page. */
    272145    PDB70PAGE   iStartPage;
     
    274147    PDB70PAGE   cPages;
    275148    /** The root stream directory. */
    276     uint32_t    cbRoot;
     149    KU32        cbRoot;
    277150    /** Unknown function, always 0. */
    278     uint32_t    u32Reserved;
     151    KU32        u32Reserved;
    279152    /** The page index of the root page table. */
    280153    PDB70PAGE   iRootPages;
     
    287160{
    288161    /** The number of streams */
    289     uint32_t    cStreams;
     162    KU32        cStreams;
    290163    /** Array of streams. */
    291164    PDB70STREAM aStreams[1];
    292     /* uint32_t aiPages[] */
     165    /* KU32 aiPages[] */
    293166} PDB70ROOT, *PPDB70ROOT;
    294167
     
    299172{
    300173    /** The structure version. */
    301     uint32_t        Version;
     174    KU32            Version;
    302175    /** Timestamp.  */
    303     uint32_t        TimeStamp;
     176    KU32            TimeStamp;
    304177    /** Unknown. */
    305     uint32_t        Unknown1;
     178    KU32            Unknown1;
    306179    /** GUID. */
    307     uint32_t        u32Guid[4];
     180    KU32            u32Guid[4];
    308181    /** The size of the following name table. */
    309     uint32_t        cbNames;
     182    KU32            cbNames;
    310183    /** The name table. */
    311184    char            szzNames[1];
     
    341214static size_t Pdb70Align(PPDB70HDR pHdr, size_t cb)
    342215{
    343     if (cb == ~(uint32_t)0 || !cb)
     216    if (cb == ~(KU32)0 || !cb)
    344217        return 0;
    345218    return ((cb + pHdr->cbPage - 1) / pHdr->cbPage) * pHdr->cbPage;
     
    349222static size_t Pdb70Pages(PPDB70HDR pHdr, size_t cb)
    350223{
    351     if (cb == ~(uint32_t)0 || !cb)
     224    if (cb == ~(KU32)0 || !cb)
    352225        return 0;
    353226    return (cb + pHdr->cbPage - 1) / pHdr->cbPage;
     
    358231    const size_t    cbPage = pHdr->cbPage;
    359232    size_t          cPages = Pdb70Pages(pHdr, cb);
    360     uint8_t *pbBuf = malloc(cPages * cbPage + 1);
     233    KU8            *pbBuf = malloc(cPages * cbPage + 1);
    361234    if (pbBuf)
    362235    {
     
    368241            {
    369242                off *= cbPage;
    370                 memcpy(pbBuf + iPage * cbPage, (uint8_t *)pHdr + off, cbPage);
     243                memcpy(pbBuf + iPage * cbPage, (KU8 *)pHdr + off, cbPage);
    371244                dump(pbBuf + iPage * cbPage, iPage + 1 < cPages ? cbPage : cb % cbPage, off);
    372245            }
     
    393266     * (Todo: Check if we can just use the stream #0 size..)
    394267     */
    395     PPDB70PAGE piPageMap = (uint32_t *)((uint8_t *)pHdr + pHdr->iRootPages * pHdr->cbPage);
     268    PPDB70PAGE piPageMap = (KU32 *)((KU8 *)pHdr + pHdr->iRootPages * pHdr->cbPage);
    396269    PPDB70ROOT pRoot = Pdb70AllocAndRead(pHdr, pHdr->cbRoot, piPageMap);
    397270    if (pRoot)
     
    400273        /* This stuff is probably unnecessary: */
    401274        /* size = stream header + array of stream. */
    402         size_t cb = OFFSETOF(PDB70ROOT, aStreams[pRoot->cStreams]);
     275        size_t cb = K_OFFSETOF(PDB70ROOT, aStreams[pRoot->cStreams]);
    403276        free(pRoot);
    404277        pRoot = Pdb70AllocAndRead(pHdr, cb, piPageMap);
     
    408281            unsigned iStream = pRoot->cStreams;
    409282            while (iStream-- > 0)
    410                 if (pRoot->aStreams[iStream].cbStream != ~(uint32_t)0)
     283                if (pRoot->aStreams[iStream].cbStream != ~(KU32)0)
    411284                    cb += Pdb70Pages(pHdr, pRoot->aStreams[iStream].cbStream) * sizeof(PDB70PAGE);
    412285            free(pRoot);
     
    431304    PPDB70PAGE      paiPageMap;
    432305    if (    iStream >= pRoot->cStreams
    433         ||  cbStream == ~(uint32_t)0)
     306        ||  cbStream == ~(KU32)0)
    434307    {
    435308        fprintf(stderr, "%s: error: Invalid stream %d\n", argv0, iStream);
     
    439312    paiPageMap = (PPDB70PAGE)&pRoot->aStreams[pRoot->cStreams];
    440313    while (iStream-- > 0)
    441         if (pRoot->aStreams[iStream].cbStream != ~(uint32_t)0)
     314        if (pRoot->aStreams[iStream].cbStream != ~(KU32)0)
    442315            paiPageMap += Pdb70Pages(pHdr, pRoot->aStreams[iStream].cbStream);
    443316
     
    447320}
    448321
    449 static int Pdb70Process(uint8_t *pbFile, size_t cbFile)
     322static int Pdb70Process(KU8 *pbFile, size_t cbFile)
    450323{
    451324    PPDB70HDR   pHdr = (PPDB70HDR)pbFile;
     
    477350        if (    pNames->Version == PDB70NAMES_VERSION
    478351            &&  pNames->cbNames > 32
    479             &&  pNames->cbNames + offsetof(PDB70NAMES, szzNames) <= pRoot->aStreams[1].cbStream)
     352            &&  pNames->cbNames + K_OFFSETOF(PDB70NAMES, szzNames) <= pRoot->aStreams[1].cbStream)
    480353        {
    481354            /*
     
    529402        for (iStream = 0; iStream < pRoot->cStreams && !rc; iStream++)
    530403        {
    531             uint8_t *pbStream;
    532             if (    pRoot->aStreams[iStream].cbStream == ~(uint32_t)0
     404            KU8 *pbStream;
     405            if (    pRoot->aStreams[iStream].cbStream == ~(KU32)0
    533406                ||  !pRoot->aStreams[iStream].cbStream)
    534407                continue;
    535408            dprintf(("Stream #%d: %#x bytes (%#x aligned)\n", iStream, pRoot->aStreams[iStream].cbStream,
    536409                     Pdb70Align(pHdr, pRoot->aStreams[iStream].cbStream)));
    537             pbStream = (uint8_t *)Pdb70AllocAndReadStream(pHdr, pRoot, iStream, &cbStream);
     410            pbStream = (KU8 *)Pdb70AllocAndReadStream(pHdr, pRoot, iStream, &cbStream);
    538411            if (pbStream)
    539412            {
     
    562435
    563436/** A PDB 2.0 Page number. */
    564 typedef uint16_t PDB20PAGE;
     437typedef KU16 PDB20PAGE;
    565438/** Pointer to a PDB 2.0 Page number. */
    566439typedef PDB20PAGE *PPDB20PAGE;
     
    572445{
    573446    /** The size of the stream. */
    574     uint32_t    cbStream;
     447    KU32        cbStream;
    575448    /** Some unknown value. */
    576     uint32_t    u32Unknown;
     449    KU32        u32Unknown;
    577450} PDB20STREAM, *PPDB20STREAM;
    578451
     
    585458{
    586459    /** The signature string. */
    587     uint8_t     szSignature[sizeof(PDB_SIGNATURE_200)];
     460    KU8         szSignature[sizeof(PDB_SIGNATURE_200)];
    588461    /** The page size. */
    589     uint32_t    cbPage;
     462    KU32        cbPage;
    590463    /** The start page - whatever that is... */
    591464    PDB20PAGE   iStartPage;
     
    604477{
    605478    /** The number of streams */
    606     uint16_t    cStreams;
     479    KU16        cStreams;
    607480    /** Reserved or high part of cStreams. */
    608     uint16_t    u16Reserved;
     481    KU16        u16Reserved;
    609482    /** Array of streams. */
    610483    PDB20STREAM aStreams[1];
     
    629502static size_t Pdb20Pages(PPDB20HDR pHdr, size_t cb)
    630503{
    631     if (cb == ~(uint32_t)0 || !cb)
     504    if (cb == ~(KU32)0 || !cb)
    632505        return 0;
    633506    return (cb + pHdr->cbPage - 1) / pHdr->cbPage;
     
    637510{
    638511    size_t cPages = Pdb20Pages(pHdr, cb);
    639     uint8_t *pbBuf = malloc(cPages * pHdr->cbPage + 1);
     512    KU8  *pbBuf = malloc(cPages * pHdr->cbPage + 1);
    640513    if (pbBuf)
    641514    {
     
    645518            size_t off = paiPageMap[iPage];
    646519            off *= pHdr->cbPage;
    647             memcpy(pbBuf + iPage * pHdr->cbPage, (uint8_t *)pHdr + off, pHdr->cbPage);
     520            memcpy(pbBuf + iPage * pHdr->cbPage, (KU8 *)pHdr + off, pHdr->cbPage);
    648521            iPage++;
    649522        }
     
    665538    {
    666539        /* size = stream header + array of stream. */
    667         size_t cb = OFFSETOF(PDB20ROOT, aStreams[pRoot->cStreams]);
     540        size_t cb = K_OFFSETOF(PDB20ROOT, aStreams[pRoot->cStreams]);
    668541        free(pRoot);
    669542        pRoot = Pdb20AllocAndRead(pHdr, cb, &pHdr->aiRootPageMap[0]);
     
    673546            unsigned iStream = pRoot->cStreams;
    674547            while (iStream-- > 0)
    675                 if (pRoot->aStreams[iStream].cbStream != ~(uint32_t)0)
     548                if (pRoot->aStreams[iStream].cbStream != ~(KU32)0)
    676549                    cb += Pdb20Pages(pHdr, pRoot->aStreams[iStream].cbStream) * sizeof(PDB20PAGE);
    677550            free(pRoot);
     
    693566    PPDB20PAGE  paiPageMap;
    694567    if (    iStream >= pRoot->cStreams
    695         ||  cbStream == ~(uint32_t)0)
     568        ||  cbStream == ~(KU32)0)
    696569    {
    697570        fprintf(stderr, "%s: error: Invalid stream %d\n", argv0, iStream);
     
    701574    paiPageMap = (PPDB20PAGE)&pRoot->aStreams[pRoot->cStreams];
    702575    while (iStream-- > 0)
    703         if (pRoot->aStreams[iStream].cbStream != ~(uint32_t)0)
     576        if (pRoot->aStreams[iStream].cbStream != ~(KU32)0)
    704577            paiPageMap += Pdb20Pages(pHdr, pRoot->aStreams[iStream].cbStream);
    705578
     
    709582}
    710583
    711 static int Pdb20Process(uint8_t *pbFile, size_t cbFile)
     584static int Pdb20Process(KU8 *pbFile, size_t cbFile)
    712585{
    713586    PPDB20HDR   pHdr = (PPDB20HDR)pbFile;
     
    732605    for (iStream = 0; iStream < pRoot->cStreams && !rc; iStream++)
    733606    {
    734         uint8_t *pbStream;
    735         if (pRoot->aStreams[iStream].cbStream == ~(uint32_t)0)
     607        KU8 *pbStream;
     608        if (pRoot->aStreams[iStream].cbStream == ~(KU32)0)
    736609            continue;
    737         pbStream = (uint8_t *)Pdb20AllocAndReadStream(pHdr, pRoot, iStream, NULL);
     610        pbStream = (KU8 *)Pdb20AllocAndReadStream(pHdr, pRoot, iStream, NULL);
    738611        if (pbStream)
    739612        {
     
    756629{
    757630    size_t      cbFile;
    758     uint8_t    *pbFile;
     631    KU8        *pbFile;
     632    void       *pvOpaque;
    759633    int         rc = 0;
    760634
     
    762636     * Read the file into memory.
    763637     */
    764     pbFile = (uint8_t *)ReadFileIntoMemory(pInput, &cbFile);
     638    pbFile = (KU8 *)depReadFileIntoMemory(pInput, &cbFile, &pvOpaque);
    765639    if (!pbFile)
    766640        return 1;
     
    779653    }
    780654
    781     FreeFileMemory(pbFile);
     655    depFreeFileMemory(pbFile, pvOpaque);
    782656    return rc;
    783657}
  • trunk/src/lib/kDep.c

    r2243 r2263  
    3535#include <sys/stat.h>
    3636#include "k/kDefs.h"
     37#include "k/kTypes.h"
    3738#if K_OS == K_OS_WINDOWS
    38 # include <windows.h>
     39# define USE_WIN_MMAP
     40# include <io.h>
     41# include <Windows.h>
    3942 extern void nt_fullpath(const char *pszPath, char *pszFull, size_t cchFull); /* nt_fullpath.c */
    4043#else
     
    294297   this is one of the algorithms used in berkeley db (see sleepycat) and
    295298   elsewhere. */
    296 static unsigned sdbm(const char *str)
     299static unsigned sdbm(const char *str, size_t size)
    297300{
    298301    unsigned hash = 0;
    299302    int c;
    300303
    301     while ((c = *(unsigned const char *)str++))
     304    while (size-- > 0 && (c = *(unsigned const char *)str++))
    302305        hash = c + (hash << 6) + (hash << 16) - hash;
    303306
     
    310313 *
    311314 * @returns Pointer to the allocated dependency.
    312  * @param   pszFilename     The filename.
     315 * @param   pszFilename     The filename. Does not need to be terminated.
    313316 * @param   cchFilename     The length of the filename.
    314317 */
    315318PDEP depAdd(const char *pszFilename, size_t cchFilename)
    316319{
    317     unsigned uHash = sdbm(pszFilename);
    318     PDEP    pDep;
    319     PDEP    pDepPrev;
     320    unsigned    uHash = sdbm(pszFilename, cchFilename);
     321    PDEP        pDep;
     322    PDEP        pDepPrev;
    320323
    321324    /*
     
    341344
    342345    pDep->cchFilename = cchFilename;
    343     memcpy(pDep->szFilename, pszFilename, cchFilename + 1);
     346    memcpy(pDep->szFilename, pszFilename, cchFilename);
     347    pDep->szFilename[cchFilename] = '\0';
    344348    pDep->uHash = uHash;
    345349
     
    373377}
    374378
     379
     380/**
     381 * Performs a hexdump.
     382 */
     383void depHexDump(const KU8 *pb, size_t cb, size_t offBase)
     384{
     385    const unsigned      cchWidth = 16;
     386    size_t              off = 0;
     387    while (off < cb)
     388    {
     389        unsigned i;
     390        printf("%s%0*x %04x:", off ? "\n" : "", sizeof(pb) * 2, offBase + off, off);
     391        for (i = 0; i < cchWidth && off + i < cb ; i++)
     392            printf(off + i < cb ? !(i & 7) && i ? "-%02x" : " %02x" : "   ", pb[i]);
     393
     394        while (i++ < cchWidth)
     395                printf("   ");
     396        printf(" ");
     397
     398        for (i = 0; i < cchWidth && off + i < cb; i++)
     399        {
     400            const KU8 u8 = pb[i];
     401            printf("%c", u8 < 127 && u8 >= 32 ? u8 : '.', 1);
     402        }
     403        off += cchWidth;
     404        pb  += cchWidth;
     405    }
     406    printf("\n");
     407}
     408
     409
     410/**
     411 * Reads the file specified by the pInput file stream into memory.
     412 *
     413 * @returns The address of the memory mapping on success. This must be
     414 *          freed by calling depFreeFileMemory.
     415 *
     416 * @param   pInput      The file stream to load or map into memory.
     417 * @param   pcbFile     Where to return the mapping (file) size.
     418 * @param   ppvOpaque   Opaque data when mapping, otherwise NULL.
     419 */
     420void *depReadFileIntoMemory(FILE *pInput, size_t *pcbFile, void **ppvOpaque)
     421{
     422    void       *pvFile;
     423    long        cbFile;
     424
     425    /*
     426     * Figure out file size.
     427     */
     428#if defined(_MSC_VER)
     429    cbFile = _filelength(fileno(pInput));
     430    if (cbFile < 0)
     431#else
     432    if (    fseek(pInput, 0, SEEK_END) < 0
     433        ||  (cbFile = ftell(pInput)) < 0
     434        ||  fseek(pInput, 0, SEEK_SET))
     435#endif
     436    {
     437        fprintf(stderr, "kDep: error: Failed to determin file size.\n");
     438        return NULL;
     439    }
     440    if (pcbFile)
     441        *pcbFile = cbFile;
     442
     443    /*
     444     * Try mmap first.
     445     */
     446#ifdef USE_WIN_MMAP
     447    {
     448        HANDLE hMapObj = CreateFileMapping((HANDLE)_get_osfhandle(fileno(pInput)),
     449                                           NULL, PAGE_READONLY, 0, cbFile, NULL);
     450        if (hMapObj != NULL)
     451        {
     452            pvFile = MapViewOfFile(hMapObj, FILE_MAP_READ, 0, 0, cbFile);
     453            if (pvFile)
     454            {
     455                *ppvOpaque = hMapObj;
     456                return pvFile;
     457            }
     458            fprintf(stderr, "kDep: warning: MapViewOfFile failed, %d.\n", GetLastError());
     459            CloseHandle(hMapObj);
     460        }
     461        else
     462            fprintf(stderr, "kDep: warning: CreateFileMapping failed, %d.\n", GetLastError());
     463    }
     464
     465#endif
     466
     467    /*
     468     * Allocate memory and read the file.
     469     */
     470    pvFile = malloc(cbFile + 1);
     471    if (pvFile)
     472    {
     473        if (fread(pvFile, cbFile, 1, pInput))
     474        {
     475            ((KU8 *)pvFile)[cbFile] = '\0';
     476            *ppvOpaque = NULL;
     477            return pvFile;
     478        }
     479        fprintf(stderr, "kDep: error: Failed to read %ld bytes.\n", cbFile);
     480        free(pvFile);
     481    }
     482    else
     483        fprintf(stderr, "kDep: error: Failed to allocate %ld bytes (file mapping).\n", cbFile);
     484    return NULL;
     485}
     486
     487
     488/**
     489 * Free resources allocated by depReadFileIntoMemory.
     490 *
     491 * @param   pvFile      The address of the memory mapping.
     492 * @param   pvOpaque    The opaque value returned together with the mapping.
     493 */
     494void depFreeFileMemory(void *pvFile, void *pvOpaque)
     495{
     496#if defined(USE_WIN_MMAP)
     497    if (pvOpaque)
     498    {
     499        UnmapViewOfFile(pvFile);
     500        CloseHandle(pvOpaque);
     501        return;
     502    }
     503#endif
     504    free(pvFile);
     505}
     506
  • trunk/src/lib/kDep.h

    r2243 r2263  
    4646extern void depPrintStubs(FILE *pOutput);
    4747extern void depCleanup(void);
     48extern void *depReadFileIntoMemory(FILE *pInput, size_t *pcbFile, void **ppvOpaque);
     49extern void depFreeFileMemory(void *pvFile, void *pvOpaque);
     50#ifdef ___k_kTypes_h___
     51extern void depHexDump(const KU8 *pb, size_t cb, size_t offBase);
     52#endif
    4853
    4954#endif
Note: See TracChangeset for help on using the changeset viewer.