VirtualBox

Changeset 1002 in kBuild for trunk/src


Ignore:
Timestamp:
Jun 2, 2007 10:13:03 AM (18 years ago)
Author:
bird
Message:

another backup commit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/kObjCache/kObjCache.c

    r1001 r1002  
    3737#include <sys/stat.h>
    3838#include <fcntl.h>
     39#include <limits.h>
     40#ifndef PATH_MAX
     41# define PATH_MAX _MAX_PATH /* windows */
     42#endif
    3943#if defined(__OS2__) || defined(__WIN__)
    4044# include <process.h>
     
    5458
    5559
    56 /* for later: */
    57 #define xmalloc     malloc
    58 #define xrealloc    realloc
    59 #define xstrdup     strdup
    60 
    61 
    6260/*******************************************************************************
    6361*   Structures and Typedefs                                                    *
     
    8886    char *pszDir;
    8987    /** The name of the cache file. */
    90     char *pszName;
     88    const char *pszName;
    9189    /** Set if the object needs to be (re)compiled. */
    9290    unsigned fNeedCompiling;
     
    137135*******************************************************************************/
    138136static const char *FindFilenameInPath(const char *pszPath);
     137static char *AbsPath(const char *pszPath);
    139138static char *MakePathFromDirAndFile(const char *pszName, const char *pszDir);
    140139static char *CalcRelativeName(const char *pszPath, const char *pszDir);
     
    144143static int DoesFileInDirExist(const char *pszName, const char *pszDir);
    145144static void *ReadFileInDir(const char *pszName, const char *pszDir, size_t *pcbFile);
     145static void *xmalloc(size_t);
     146static void *xrealloc(void *, size_t);
     147static char *xstrdup(const char *);
     148
    146149
    147150/* crc.c */
     
    172175
    173176/**
    174  * Creates a cache entry for the given cache file name.
    175  * 
    176  * @returns Pointer to a cache entry.
    177  * @param   pszFilename     The cache file name.
    178  */
    179 static PKOBJCACHE kObjCacheCreate(const char *pszFilename)
    180 {
    181     PKOBJCACHE pEntry;
    182     const char *pszDir;
    183     size_t cchDir;
    184 
    185     /*
    186      * Allocate an empty entry.
    187      */
    188     pEntry = xmalloc(sizeof(*pEntry));
    189     memset(pEntry, 0, sizeof(*pEntry));
    190 
    191     /*
    192      * Setup the directory and cache file name.
    193      */
    194     pszDir = pszFilename;
    195     assert(*pszFilename);
    196     pszFilename = FindFilenameInPath(pszFilename);
    197     if (pszFilename <= pszDir)
    198     {
    199         pszDir = "./";
    200         cchDir = 2;
    201     }
    202     else
    203         cchDir = pszFilename - pszDir; /* includes the separator */
    204 
    205     pEntry->pszDir = xmalloc(cchDir + 1);
    206     memcpy(pEntry->pszDir, pszDir, cchDir);
    207     pEntry->pszDir[cchDir] = '\0';
    208     pEntry->pszName = xstrdup(pszFilename);
    209 
    210     return pEntry;
    211 }
    212 
    213 
    214 #if 0 /* don't bother. */
    215 /**
    216  * Destroys the cache entry freeing up all it's resources.
    217  * 
    218  * @param   pEntry      The entry to free.
    219  */
    220 static void kObjCacheDestroy(PKOBJCACHE pEntry)
    221 {
    222     free(pEntry->pszDir);
    223     free(pEntry->pszName);
    224     while (pEntry->SumHead.pNext)
    225     {
    226         void *pv = pEntry->SumHead.pNext;
    227         pEntry->SumHead.pNext = pEntry->SumHead.pNext->pNext;
    228         if (pv != &pEntry->NewSum)
    229             free(pv);
    230     }
    231     free(pEntry);
    232 }
    233 #endif
    234 
    235 
    236 /**
    237177 * Print a fatal error message and exit with rc=1.
    238178 *
     
    276216
    277217/**
     218 * Creates a cache entry for the given cache file name.
     219 * 
     220 * @returns Pointer to a cache entry.
     221 * @param   pszFilename     The cache file name.
     222 */
     223static PKOBJCACHE kObjCacheCreate(const char *pszFilename)
     224{
     225    PKOBJCACHE pEntry;
     226
     227    /*
     228     * Allocate an empty entry.
     229     */
     230    pEntry = xmalloc(sizeof(*pEntry));
     231    memset(pEntry, 0, sizeof(*pEntry));
     232
     233    /*
     234     * Setup the directory and cache file name.
     235     */
     236    pEntry->pszDir = AbsPath(pszFilename);
     237    pEntry->pszName = FindFilenameInPath(pEntry->pszDir);
     238    if (pEntry->pszDir == pEntry->pszName)
     239        kObjCacheFatal(pEntry, "Failed to find abs path for '%s'!\n", pszFilename);
     240    ((char *)pEntry->pszName)[-1] = '\0';
     241
     242    return pEntry;
     243}
     244
     245
     246#if 0 /* don't bother. */
     247/**
     248 * Destroys the cache entry freeing up all it's resources.
     249 * 
     250 * @param   pEntry      The entry to free.
     251 */
     252static void kObjCacheDestroy(PKOBJCACHE pEntry)
     253{
     254    free(pEntry->pszDir);
     255    free(pEntry->pszName);
     256    while (pEntry->SumHead.pNext)
     257    {
     258        void *pv = pEntry->SumHead.pNext;
     259        pEntry->SumHead.pNext = pEntry->SumHead.pNext->pNext;
     260        if (pv != &pEntry->NewSum)
     261            free(pv);
     262    }
     263    free(pEntry);
     264}
     265#endif
     266
     267
     268/**
    278269 * Reads and parses the cache file.
    279270 * 
     
    282273static void kObjCacheRead(PKOBJCACHE pEntry)
    283274{
    284 
     275    kObjCacheVerbose(pEntry, "reading cache file...\n");
     276    pEntry->fNeedCompiling = 1;
    285277}
    286278
     
    293285static void kObjCacheWrite(PKOBJCACHE pEntry)
    294286{
     287    kObjCacheVerbose(pEntry, "writing cache file...\n");
    295288   
    296289}
     
    304297 * @param   cArgv           The number of arguments in the vector.
    305298 */
    306 static void kObjCacheSpawn(PCKOBJCACHE pEntry, const char **papszArgv, unsigned cArgv, const char *pszMsg)
    307 {
    308 #if defined(__OS2__)
    309     int rc = _spawnvp(_P_WAIT, papszArgv[0], papszArgv);
    310     if (rc)
    311         kObjCacheFatal(pEntry, "%s - _spawnvp / command failed, rc=%#x\n", pszMsg, rc);
    312 
    313 #elif defined(__WIN__)
    314     intptr_t rc = _spawnvp(_P_WAIT, papszArgv[0], papszArgv);
    315     if (rc)
    316         kObjCacheFatal(pEntry, "%s - _spawnvp / command failed, rc=0x%p\n", pszMsg, rc);
     299static void kObjCacheSpawn(PCKOBJCACHE pEntry, const char **papszArgv, unsigned cArgv, const char *pszMsg, const char *pszStdOut)
     300{
     301#if defined(__OS2__) || defined(__WIN__)
     302    intptr_t rc;
     303    int fdStdOut = -1;
     304    if (pszStdOut)
     305    {
     306        int fdReDir;
     307        fdStdOut = dup(1); /* dup2(1,-1) doesn't work right on windows */
     308        close(1);
     309        fdReDir = open(pszStdOut, O_CREAT | O_TRUNC | O_WRONLY, 0777);
     310        if (fdReDir < 0)
     311            kObjCacheFatal(pEntry, "%s - failed to create stdout redirection file '%s': %s\n",
     312                           pszMsg, pszStdOut, strerror(errno));
     313        if (fdReDir != 1)
     314        {
     315            if (dup2(fdReDir, 1) < 0)
     316                kObjCacheFatal(pEntry, "%s - dup2 failed: %s\n", pszMsg, strerror(errno));
     317            close(fdReDir);
     318        }
     319    }
     320
     321    errno = 0;
     322    rc = _spawnvp(_P_WAIT, papszArgv[0], papszArgv);
     323    if (rc < 0)
     324        kObjCacheFatal(pEntry, "%s - _spawnvp failed (rc=0x%p): %s\n", pszMsg, rc, strerror(errno));
     325    if (rc > 0)
     326        kObjCacheFatal(pEntry, "%s - failed rc=%d\n", pszMsg, (int)rc);
     327    if (fdStdOut)
     328    {
     329        close(1);
     330        fdStdOut = dup2(fdStdOut, 1);
     331        close(fdStdOut);
     332    }
    317333
    318334#else
     
    322338    if (!pid)
    323339    {
     340        if (pszStdOut)
     341        {
     342            close(1);
     343            fdReDir = open(pszStdOut, O_CREAT | O_TRUNC | O_WRONLY, 0777);
     344            if (fdReDir < 0)
     345                kObjCacheFatal(pEntry, "%s - failed to create stdout redirection file '%s': %s\n",
     346                               pszMsg, pszStdOut, strerror(errno));
     347            if (fdReDir != 1)
     348            {
     349                if (dup2(fdReDir, 1) < 0)
     350                    kObjCacheFatal(pEntry, "%s - dup2 failed: %s\n", pszMsg, strerror(errno));
     351                close(fdReDir);
     352            }
     353        }
     354
    324355        execvp(papszArgv[0], papszArgv);
    325356        kObjCacheFatal(pEntry, "%s - execvp failed rc=%d errno=%d %s\n",
     
    357388     */
    358389    pEntry->pszNewCppMapping = ReadFileInDir(pEntry->pszNewCppName, pEntry->pszDir, &pEntry->cbNewCppMapping);
    359     if (pEntry->pszNewCppMapping)
     390    if (!pEntry->pszNewCppMapping)
    360391        kObjCacheFatal(pEntry, "failed to open/read '%s' in '%s': %s\n",
    361392                       pEntry->pszNewCppName, pEntry->pszDir, strerror(errno));
     393    kObjCacheVerbose(pEntry, "precompiled file is %lu bytes long\n", (unsigned long)pEntry->cbNewCppMapping);
    362394
    363395    pEntry->NewSum.crc32 = crc32(0, pEntry->pszNewCppMapping, pEntry->cbNewCppMapping);
     
    365397    MD5Update(&MD5Ctx, pEntry->pszNewCppMapping, pEntry->cbNewCppMapping);
    366398    MD5Final(&pEntry->NewSum.md5[0], &MD5Ctx);
     399    kObjCacheVerbose(pEntry, "crc32=%#lx md5=08x%08x%08x%08x\n", pEntry->NewSum.crc32,
     400                     ((uint32_t *)&pEntry->NewSum.md5[0])[0],
     401                     ((uint32_t *)&pEntry->NewSum.md5[0])[1],
     402                     ((uint32_t *)&pEntry->NewSum.md5[0])[2],
     403                     ((uint32_t *)&pEntry->NewSum.md5[0])[3]);
    367404}
    368405
     
    375412 * @param   cArgvPreComp        The number of arguments.
    376413 * @param   pszPreCompName      Precompile output name. (must kick around)
    377  */
    378 static void kObjCachePreCompile(PKOBJCACHE pEntry, const char **papszArgvPreComp, unsigned cArgvPreComp, const char *pszPreCompName)
     414 * @param   fRedirStdOut        Whether stdout needs to be redirected or not.
     415 */
     416static void kObjCachePreCompile(PKOBJCACHE pEntry, const char **papszArgvPreComp, unsigned cArgvPreComp, const char *pszPreCompName, int fRedirStdOut)
    379417{
    380418    /*
     
    383421     * we might with to do a quick matchup later we can't remove it just now.
    384422     */
    385     if (pEntry->pszOldCppName)
     423    if (    pEntry->pszOldCppName
     424        &&  DoesFileInDirExist(pEntry->pszOldCppName, pEntry->pszDir))
    386425    {
    387426        size_t cch = strlen(pEntry->pszOldCppName);
     
    390429        memcpy(psz + cch, "-old", sizeof("-old"));
    391430
     431        kObjCacheVerbose(pEntry, "renaming '%s' to '%s' in '%s'\n", pEntry->pszOldCppName, psz, pEntry->pszDir);
    392432        UnlinkFileInDir(psz, pEntry->pszDir);
    393433        if (RenameFileInDir(pEntry->pszOldCppName, psz, pEntry->pszDir))
     
    397437        pEntry->pszOldCppName = psz;
    398438    }
    399     pEntry->pszNewCppName = pszPreCompName;
     439    pEntry->pszNewCppName = CalcRelativeName(pszPreCompName, pEntry->pszDir);
    400440
    401441    /*
    402442     * Precompile it and calculate the checksum on the output.
    403443     */
    404     if (!pszPreCompName)
    405     {
    406         kObjCacheFatal(pEntry, "redirection feature is not implemented\n");
    407         /** @todo piped output. */
    408     }
    409     kObjCacheSpawn(pEntry, papszArgvPreComp, cArgvPreComp, "precompile");
     444    kObjCacheVerbose(pEntry, "precompiling -> '%s'...\n", pEntry->pszNewCppName);
     445    if (fRedirStdOut)
     446        kObjCacheSpawn(pEntry, papszArgvPreComp, cArgvPreComp, "precompile", pszPreCompName);
     447    else
     448        kObjCacheSpawn(pEntry, papszArgvPreComp, cArgvPreComp, "precompile", NULL);
    410449    kObjCacheCalcChecksum(pEntry);
    411450}
     
    449488        pEntry->pszObjName = NULL;
    450489    }
    451     pEntry->pszNewObjName = CalcRelativeName(pEntry->pszDir, pszObjName);
     490    pEntry->pszNewObjName = CalcRelativeName(pszObjName, pEntry->pszDir);
    452491
    453492    /*
     
    462501     * Do the recompilation.
    463502     */
     503    kObjCacheVerbose(pEntry, "compiling -> '%s'...\n", pEntry->pszNewObjName);
    464504    pEntry->papszArgvCompile = papszArgvCompile;
    465505    pEntry->cArgvCompile = cArgvCompile;
    466     kObjCacheSpawn(pEntry, papszArgvCompile, cArgvCompile, "compile");
     506    kObjCacheSpawn(pEntry, papszArgvCompile, cArgvCompile, "compile", NULL);
    467507}
    468508
     
    482522     * Does the object name differ?
    483523     */
    484     if (    !pEntry->fNeedCompiling
    485         &&  strcmp(FindFilenameInPath(pszObjName), pEntry->pszObjName))
    486     {
    487         pEntry->fNeedCompiling = 1;
    488         kObjCacheVerbose(pEntry, "object name changed\n");
     524    if (!pEntry->fNeedCompiling)
     525    {
     526        char *pszTmp = CalcRelativeName(pszObjName, pEntry->pszDir);
     527        if (strcmp(pEntry->pszObjName, pszTmp))
     528        {
     529            pEntry->fNeedCompiling = 1;
     530            kObjCacheVerbose(pEntry, "object name changed '%s' -> '%s'\n", pEntry->pszObjName, pszTmp);
     531        }
     532        free(pszTmp);
    489533    }
    490534
     
    514558     * Does the object file exist?
    515559     */
    516     if (!DoesFileInDirExist(pEntry->pszObjName, pEntry->pszDir))
     560    if (    !pEntry->fNeedCompiling
     561        &&  !DoesFileInDirExist(pEntry->pszObjName, pEntry->pszDir))
    517562    {
    518563        pEntry->fNeedCompiling = 1;
     
    562607    if (pEntry->fNeedCompiling)
    563608        kObjCacheCompileIt(pEntry, papszArgvCompile, cArgvCompile, pszObjName);
     609}
     610
     611
     612/**
     613 * Gets the absolute path
     614 *
     615 * @returns A new heap buffer containing the absolute path.
     616 * @param   pszPath     The path to make absolute. (Readonly)
     617 */
     618static char *AbsPath(const char *pszPath)
     619{
     620    char szTmp[PATH_MAX];
     621#if defined(__OS2__) || defined(__WIN__)
     622    if (!_fullpath(szTmp, *pszPath ? pszPath : ".", sizeof(szTmp)))
     623        return xstrdup(pszPath);
     624#else
     625    if (!realpath(pszPath, szTmp))
     626        return xstrdup(pszPath);
     627#endif
     628   return xstrdup(szTmp);
    564629}
    565630
     
    610675
    611676/**
    612  * Calculate how to get to pszPath from pszDir.
    613  *
    614  * @returns The relative path from pszDir to path pszPath.
    615  * @param   pszPath     The path to the object.
    616  * @param   pszDir      The directory it shall be relative to.
    617  */
    618 static char *CalcRelativeName(const char *pszPath, const char *pszDir)
    619 {
    620     size_t cchDir = strlen(pszDir);
     677 * Compares two path strings to see if they are identical.
     678 *
     679 * This doesn't do anything fancy, just the case ignoring and
     680 * slash unification.
     681 *
     682 * @returns 1 if equal, 0 otherwise.
     683 * @param   pszPath1    The first path.
     684 * @param   pszPath2    The second path.
     685 * @param   cch         The number of characters to compare.
     686 */
     687static int ArePathsIdentical(const char *pszPath1, const char *pszPath2, size_t cch)
     688{
    621689#if defined(__OS2__) || defined(__WIN__)
    622     int fMatches;
    623 #endif
    624 
    625     /*
    626      * This is indeed a bit tricky, so we'll try the easy way first...
    627      */
    628 #if defined(__OS2__) || defined(__WIN__)
    629     fMatches = strnicmp(pszPath, pszDir, cchDir);
    630     if (!fMatches)
     690    if (strnicmp(pszPath1, pszPath2, cch))
    631691    {
    632692        /* Slashes may differ, compare char by char. */
    633         const char *psz1 = pszDir;
    634         const char *psz2 = pszPath;
    635         fMatches = 1;
    636         for (;; psz1++, psz2++)
     693        const char *psz1 = pszPath1;
     694        const char *psz2 = pszPath2;
     695        for (;cch; psz1++, psz2++, cch--)
    637696        {
    638697            if (*psz1 != *psz2)
    639698            {
    640                 if (!*psz1) /* dir */
    641                     break;
    642699                if (    tolower(*psz1) != tolower(*psz2)
    643700                    &&  toupper(*psz1) != toupper(*psz2)
     
    646703                    &&  *psz2 != '/'
    647704                    &&  *psz2 != '\\')
    648                 {
    649                     fMatches = 0;
    650                     break;
    651                 }
     705                    return 0;
    652706            }
    653707        }
    654708    }
    655     if (fMatches)
     709    return 1;
    656710#else
    657     if (!strncmp(pszPath, pszDir, cchDir))
     711    return !strncmp(pszPath1, pszPath2, cch);
    658712#endif
     713}
     714
     715
     716/**
     717 * Calculate how to get to pszPath from pszDir.
     718 *
     719 * @returns The relative path from pszDir to path pszPath.
     720 * @param   pszPath     The path to the object.
     721 * @param   pszDir      The directory it shall be relative to.
     722 */
     723static char *CalcRelativeName(const char *pszPath, const char *pszDir)
     724{
     725    char *pszRet = NULL;
     726    char *pszAbsPath = NULL;
     727    size_t cchDir = strlen(pszDir);
     728
     729    /*
     730     * This is indeed a bit tricky, so we'll try the easy way first...
     731     */
     732    if (ArePathsIdentical(pszPath, pszDir, cchDir))
    659733    {
    660734        if (pszPath[cchDir])
    661             return xstrdup(pszPath + cchDir);
    662         return xstrdup("./");
     735            pszRet = (char *)pszPath + cchDir;
     736        else
     737            pszRet = "./";
     738    }
     739    else
     740    {
     741        pszAbsPath = AbsPath(pszPath);
     742        if (ArePathsIdentical(pszAbsPath, pszDir, cchDir))
     743        {
     744            if (pszPath[cchDir])
     745                pszRet = pszAbsPath + cchDir;
     746            else
     747                pszRet = "./";
     748        }
     749    }
     750    if (pszRet)
     751    {
     752#if defined(__OS2__) || defined(__WIN__)
     753        while (*pszRet == ':' || *pszRet == '/' || *pszRet == '\\')
     754#else
     755        while (*pszRet == '/')
     756#endif
     757            pszRet++;
     758        pszRet = xstrdup(pszRet);
     759        free(pszAbsPath);
     760        return pszRet;
    663761    }
    664762
     
    795893
    796894
     895static void *xmalloc(size_t cb)
     896{
     897    void *pv = malloc(cb);
     898    if (!pv)
     899        kObjCacheFatal(NULL, "out of memory (%d)\n", (int)cb);
     900    return pv;
     901}
     902
     903
     904static void *xrealloc(void *pvOld, size_t cb)
     905{
     906    void *pv = realloc(pvOld, cb);
     907    if (!pv)
     908        kObjCacheFatal(NULL, "out of memory (%d)\n", (int)cb);
     909    return pv;
     910}
     911
     912
     913static char *xstrdup(const char *pszIn)
     914{
     915    char *psz = strdup(pszIn);
     916    if (!psz)
     917        kObjCacheFatal(NULL, "out of memory (%d)\n", (int)strlen(pszIn));
     918    return psz;
     919}
     920
    797921
    798922/**
     
    820944static int usage(void)
    821945{
    822     printf("syntax: kObjCache [-v|--verbose] [-f|--file] <cache-file> [-V|--version]\n"
     946    printf("syntax: kObjCache [-v|--verbose] [-f|--file] <cache-file> [-V|--version] [-r|--redir-stdout]\n"
    823947           "                  --kObjCache-cpp <filename> <precompiler + args> \n"
    824948           "                  --kObjCache-cc <object> <compiler + args>\n"
     
    839963    unsigned cArgvPreComp = 0;
    840964    const char *pszPreCompName = NULL;
     965    int fRedirStdOut = 0;
    841966
    842967    const char **papszArgvCompile = NULL;
     
    866991        {
    867992            enmMode = kOC_CcArgv;
    868             if (pszObjName)
     993            if (!pszObjName)
    869994            {
    870995                if (++i >= argc)
     
    8821007            {
    8831008                if (!(cArgvPreComp % 16))
    884                 {
    885                     cArgvPreComp += 16;
    886                     papszArgvPreComp = xrealloc((void *)papszArgvPreComp, (cArgvPreComp + 2) * sizeof(papszArgvPreComp[0]));
    887                 }
     1009                    papszArgvPreComp = xrealloc((void *)papszArgvPreComp, (cArgvPreComp + 17) * sizeof(papszArgvPreComp[0]));
    8881010                papszArgvPreComp[cArgvPreComp++] = argv[i];
    8891011                papszArgvPreComp[cArgvPreComp] = NULL;
     
    8921014            {
    8931015                if (!(cArgvCompile % 16))
    894                 {
    895                     cArgvCompile += 16;
    896                     papszArgvCompile = xrealloc((void *)papszArgvCompile, (cArgvCompile + 2) * sizeof(papszArgvCompile[0]));
    897                 }
     1016                    papszArgvCompile = xrealloc((void *)papszArgvCompile, (cArgvCompile + 17) * sizeof(papszArgvCompile[0]));
    8981017                papszArgvCompile[cArgvCompile++] = argv[i];
    8991018                papszArgvCompile[cArgvCompile] = NULL;
     
    9061025            pszCacheFile = argv[++i];
    9071026        }
     1027        else if (!strcmp(argv[i], "-r") || !strcmp(argv[i], "--redir-stdout"))
     1028            fRedirStdOut = 1;
    9081029        else if (!strcmp(argv[i], "-v") || !strcmp(argv[i], "--verbose"))
    9091030            g_fVerbose = 1;
     
    9361057     * Do the compiling.
    9371058     */
    938     kObjCachePreCompile(pEntry, papszArgvPreComp, cArgvPreComp, pszPreCompName);
     1059    kObjCachePreCompile(pEntry, papszArgvPreComp, cArgvPreComp, pszPreCompName, fRedirStdOut);
    9391060    kObjCacheCompileIfNeeded(pEntry, papszArgvCompile, cArgvCompile, pszObjName);
    9401061
     
    9481069}
    9491070
    950 
Note: See TracChangeset for help on using the changeset viewer.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette