Changeset 3134 for trunk/tools


Ignore:
Timestamp:
Mar 17, 2000, 5:26:32 AM (26 years ago)
Author:
bird
Message:

Two new options: -cy and -ca.
Optional cyclic dependancy check implemented.
The rules list is now a AVL tree.
All files but the object files are "normalized". Ie. fullnames and DOS
styled slashes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/fastdep/fastdep.c

    r3133 r3134  
    1 /* $Id: fastdep.c,v 1.11 2000-03-16 23:53:34 bird Exp $
     1/* $Id: fastdep.c,v 1.12 2000-03-17 04:26:32 bird Exp $
    22 *
    33 * Fast dependents. (Fast = Quick and Dirty!)
     
    2323#include <string.h>
    2424#include <stdlib.h>
     25#include <direct.h>
    2526
    2627#include "avl.h"
     
    8687    const char *    pszObjectExt;
    8788    const char *    pszObjectDir;
    88     BOOL            fObjectDir;        /* replace object directory? */
     89    BOOL            fObjectDir;         /* replace object directory? */
    8990    const char *    pszRsrcExt;
    9091    BOOL            fObjRule;
     
    9293    BOOL            fSrcWhenObj;
    9394    BOOL            fAppend;            /* append to the output file, not overwrite it. */
     95    BOOL            fCheckCyclic;       /* allways check for cylic dependency before inserting an dependent. */
     96    BOOL            fCacheSearchDirs;   /* cache entire search dirs. */
    9497} OPTIONS, *POPTIONS;
    9598
     
    122125typedef struct _DepRule
    123126{
     127    AVLNODECORE      avlCore;
    124128    char *           pszRule;          /* Pointer to rule name */
    125129    int              cDeps;            /* Entries in the dependant array. */
    126130    char **          papszDep;         /* Pointer to an array of pointers to dependants. */
    127     struct _DepRule *pNext;            /* Pointer to the next rule */
    128131} DEPRULE, *PDEPRULE;
    129132
     
    153156/* file operations */
    154157static char *fileNormalize(char *pszFilename);
     158static char *fileNormalize2(const char *pszFilename, char *pszBuffer);
    155159       char *filePath(const char *pszFilename, char *pszBuffer);
    156160static char *filePathSlash(const char *pszFilename, char *pszBuffer);
     
    167171
    168172/* pathlist operations */
    169 static char *pathlistFindFile(const char *pszPathList, const char *pszFilename, char *pszBuffer);
     173static char *pathlistFindFile(const char *pszPathList, const char *pszFilename, char *pszBuffer, POPTIONS pOptions);
    170174
    171175/* word operations */
     
    189193
    190194/* depend workers */
    191 static BOOL  depReadFile(const char *pszFilename);
     195static BOOL  depReadFile(const char *pszFilename, POPTIONS pOptions);
    192196static BOOL  depWriteFile(const char *pszFilename);
    193197static void  depRemoveAll(void);
    194198static void *depAddRule(const char *pszRulePath, const char *pszName, const char *pszExt);
    195 static BOOL  depAddDepend(void *pvRule, const char *pszDep);
     199static BOOL  depAddDepend(void *pvRule, const char *pszDep, BOOL fCheckCyclic);
    196200#if 0  /* not used */
    197201static BOOL  depCleanFile(const char *pszFilename);
    198202#endif
     203static BOOL  depCheckCyclic(PDEPRULE pdepRule, const char *pszDep);
    199204
    200205
     
    205210 * Pointer to the list of dependencies.
    206211 */
    207 static PDEPRULE pdepList = NULL;
    208 static BOOL     fCacheSearchDirs = FALSE;
     212static PDEPRULE pdepTree = NULL;
    209213
    210214
     
    215219static unsigned     cfcNodes = 0;
    216220static PFCACHEENTRY pfcDirTree = NULL;
     221
     222
     223/*
     224 * Current directory stuff
     225 */
     226static char     szCurDir[CCHMAXPATH];
     227static int      aiSlashes[CCHMAXPATH];
     228static int      cSlashes;
    217229
    218230
     
    279291    int         rc   = 0;
    280292    int         argi = 1;
     293    int         i;
    281294    const char *pszDepFile = pszDefaultDepFile;
    282295
     
    299312        FALSE,           /* fNoObjectPath */
    300313        TRUE,            /* fSrcWhenObj */
    301         FALSE            /* fAppend */
     314        FALSE,           /* fAppend */
     315        TRUE,            /* fCheckCyclic */
     316        TRUE             /* fCacheSearchDirs */
    302317    };
    303318
     
    310325    }
    311326
     327    /*
     328     * Initiate current directory stuff
     329     */
     330    if (_getcwd(szCurDir, sizeof(szCurDir)) == NULL)
     331    {
     332        fprintf(stderr, "fatal error: failed to get current directory\n");
     333        return -88;
     334    }
     335    strlwr(szCurDir);
     336    for (i = 0, cSlashes; szCurDir[i] != '\0'; i++)
     337    {
     338        if (szCurDir[i] == '/')
     339            szCurDir[i] = '\\';
     340        if (szCurDir[i] == '\\')
     341            aiSlashes[cSlashes++] = i;
     342    }
     343    if (szCurDir[i-1] != '\\')
     344    {
     345        aiSlashes[cSlashes] = i;
     346        szCurDir[i++] = '\\';
     347        szCurDir[i] = '\0';
     348    }
     349
     350    /*
     351     * parse arguments
     352     */
    312353    while (argi < argc)
    313354    {
     
    340381
    341382                    /* if dependencies are generated we'll flush them to the old filename */
    342                     if (pdepList != NULL && pszOld != pszDepFile)
     383                    if (pdepTree != NULL && pszOld != pszDepFile)
    343384                    {
    344385                        if (!depWriteFile(pszOld))
     
    348389                    break;
    349390                }
     391
     392                case 'C': /* forced directory cache  'ca' or cylic check 'cy'*/
     393                case 'c':
     394                    if (argv[argi][2] == 'a' || argv[argi][2] == 'A')
     395                        options.fCacheSearchDirs = TRUE;
     396                    else if ((argv[argi][2] == 'y' || argv[argi][2] == 'Y'))
     397                        options.fCheckCyclic = argv[argi][3] != '-';
     398                    break;
    350399
    351400                case 'E': /* list of paths. If a file is found in one of these directories the */
     
    470519             * before starting adding new dependencies.
    471520             */
    472             if (pdepList == NULL && options.fAppend)
    473                 depReadFile(pszDepFile);
     521            if (pdepTree == NULL && options.fAppend)
     522                depReadFile(pszDepFile, &options);
    474523
    475524            /*
     
    479528                                FILE_READONLY |  FILE_HIDDEN | FILE_SYSTEM | FILE_ARCHIVED,
    480529                                pfindbuf3, sizeof(achBuffer), &cFiles, FIL_STANDARD);
    481             if (!fCacheSearchDirs)
    482                 fCacheSearchDirs = cFiles > 25;
     530            if (!options.fCacheSearchDirs)
     531                options.fCacheSearchDirs = cFiles > 25;
    483532            while (ulRc == NO_ERROR)
    484533            {
     
    539588{
    540589    printf(
    541         "FastDep v0.1\n"
    542         "Quick and dirty dependant scanner. Creates a makefile readable depend file.\n"
     590        "FastDep v0.2\n"
     591        "Quick and dirty dependency scanner. Creates a makefile readable depend file.\n"
    543592        "\n"
    544         "Syntax: FastDep [-a<[+]|->] [-d <outputfn>] [-e <excludepath>] [-eall<[+]|->]\n"
    545         "                [-i <include>] [-n<[+]|->] [-o <objdir>] [-obr<[+]|->] <files>\n"
     593        "Syntax: FastDep [-a<[+]|->] [-ca] [-cy<[+]|->] [-d <outputfn>]\n"
     594        "                [-e <excludepath>] [-eall<[+]|->] [-i <include>] [-n<[+]|->]\n"
     595        "                [-o <objdir>] [-obr<[+]|->]  <files>\n"
    546596        "\n"
    547597        "   -a<[+]|->       Append to the output file. Default: Overwrite.\n"
     598        "   -ca             Force search directory caching.\n"
     599        "                   Default: cache if more that 25 files are to be searched.\n"
     600        "                            (more than 25 in the first file expression.)\n"
     601        "   -cy<[+]|->      Check for cylic dependencies. Default: -cy-\n"
    548602        "   -d <outputfn>   Output filename. Default: %s\n"
    549603        "   -e excludepath  Exclude paths. If a filename is found in any\n"
     
    565619        "   -r[ ]<rsrcext>  Resource binary extention.  Default: res\n"
    566620        "   <files>         Files to scan. Wildchars are allowed.\n"
    567         "\n",
     621        "\n"
     622        " copyright (c) 1999-2000 knut st. osmundsen (knut.stange.osmundsen@pmsc.no)\n",
    568623        pszDefaultDepFile
    569624        );
     
    676731
    677732        if (pOptions->fSrcWhenObj && pvRule)
    678             depAddDepend(pvRule, pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : pszFilename);
     733            depAddDepend(pvRule,
     734                         pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer),
     735                         pOptions->fCheckCyclic);
    679736    }
    680737    else
    681         pvRule = depAddRule(pszFilename, NULL, NULL);
     738        pvRule = depAddRule(pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer), NULL, NULL);
    682739
    683740    /* duplicate rule? */
     
    773830
    774831                    /* find include file! */
    775                     psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer);
     832                    psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer, pOptions);
    776833                    if (psz == NULL)
    777                         psz = pathlistFindFile(getenv("INCLUDE"), szFullname, szBuffer);
     834                        psz = pathlistFindFile(getenv("INCLUDE"), szFullname, szBuffer, pOptions);
    778835
    779836                    /* did we find the include? */
     
    782839                        char    szBuffer2[CCHMAXPATH];
    783840                        if (pOptions->fExcludeAll ||
    784                             pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2) != NULL
     841                            pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2, pOptions) != NULL
    785842                            )
    786                             depAddDepend(pvRule, szFullname);
     843                            depAddDepend(pvRule, szFullname, pOptions->fCheckCyclic);
    787844                        else
    788                             depAddDepend(pvRule, szBuffer);
     845                            depAddDepend(pvRule, szBuffer, pOptions->fCheckCyclic);
    789846                    }
    790847                    else
     
    939996
    940997        if (pOptions->fSrcWhenObj && pvRule)
    941             depAddDepend(pvRule, pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : pszFilename);
     998            depAddDepend(pvRule,
     999                         pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer),
     1000                         pOptions->fCheckCyclic);
    9421001    }
    9431002    else
    944         pvRule = depAddRule(pszFilename, NULL, NULL);
     1003        pvRule = depAddRule(pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer), NULL, NULL);
    9451004
    9461005    /* duplicate rule? */
     
    9961055
    9971056            /* find include file! */
    998             psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer);
     1057            psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer, pOptions);
    9991058            if (psz == NULL)
    1000                 psz = pathlistFindFile(getenv("INCLUDE"), szFullname, szBuffer);
     1059                psz = pathlistFindFile(getenv("INCLUDE"), szFullname, szBuffer, pOptions);
    10011060
    10021061            /* Did we find the include? */
     
    10051064                char szBuffer2[CCHMAXPATH];
    10061065                if (pOptions->fExcludeAll ||
    1007                     pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2) != NULL
     1066                    pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2, pOptions) != NULL
    10081067                    )
    1009                     depAddDepend(pvRule, szFullname);
     1068                    depAddDepend(pvRule, szFullname, pOptions->fCheckCyclic);
    10101069                else
    1011                     depAddDepend(pvRule, szBuffer);
     1070                    depAddDepend(pvRule, szBuffer, pOptions->fCheckCyclic);
    10121071            }
    10131072            else
     
    10551114
    10561115        if (pOptions->fSrcWhenObj && pvRule)
    1057             depAddDepend(pvRule, pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : pszFilename);
     1116            depAddDepend(pvRule,
     1117                         pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer),
     1118                         pOptions->fCheckCyclic);
    10581119    }
    10591120    else
    1060         pvRule = depAddRule(pszFilename, NULL, NULL);
     1121        pvRule = depAddRule(pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer), NULL, NULL);
    10611122
    10621123    /* duplicate rule? */
     
    11141175
    11151176            /* find include file! */
    1116             psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer);
     1177            psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer, pOptions);
    11171178            if (psz == NULL)
    1118                 psz = pathlistFindFile(getenv("INCLUDE"), szFullname, szBuffer);
     1179                psz = pathlistFindFile(getenv("INCLUDE"), szFullname, szBuffer, pOptions);
    11191180
    11201181            /* did we find the include? */
     
    11231184                char szBuffer2[CCHMAXPATH];
    11241185                if (pOptions->fExcludeAll ||
    1125                     pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2) != NULL
     1186                    pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2, pOptions) != NULL
    11261187                    )
    1127                     depAddDepend(pvRule, szFullname);
     1188                    depAddDepend(pvRule, szFullname, pOptions->fCheckCyclic);
    11281189                else
    1129                     depAddDepend(pvRule, szBuffer);
     1190                    depAddDepend(pvRule, szBuffer, pOptions->fCheckCyclic);
    11301191            }
    11311192            else
     
    11731234
    11741235        if (pOptions->fSrcWhenObj && pvRule)
    1175             depAddDepend(pvRule, pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : pszFilename);
     1236            depAddDepend(pvRule,
     1237                         pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer),
     1238                         pOptions->fCheckCyclic);
    11761239    }
    11771240    else
    1178         pvRule = depAddRule(pszFilename, NULL, NULL);
     1241        pvRule = depAddRule(pOptions->fExcludeAll ? fileName(pszFilename, szBuffer) : fileNormalize2(pszFilename, szBuffer), NULL, NULL);
    11791242
    11801243    /* duplicate rule? */
     
    12641327
    12651328            /* find include file! */
    1266             psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer);
     1329            psz = pathlistFindFile(pOptions->pszInclude, szFullname, szBuffer, pOptions);
    12671330
    12681331            /* did we find the include? */
     
    12711334                char szBuffer2[CCHMAXPATH];
    12721335                if (pOptions->fExcludeAll ||
    1273                     pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2) != NULL
     1336                    pathlistFindFile(pOptions->pszExclude, szFullname, szBuffer2, pOptions) != NULL
    12741337                    )
    1275                     depAddDepend(pvRule, szFullname);
     1338                    depAddDepend(pvRule, szFullname, pOptions->fCheckCyclic);
    12761339                else
    1277                     depAddDepend(pvRule, szBuffer);
     1340                    depAddDepend(pvRule, szBuffer, pOptions->fCheckCyclic);
    12781341            }
    12791342            else
     
    13221385
    13231386/**
    1324  * Normalizes the path slashes for the filename.
     1387 * Normalizes the path slashes for the filename. It will partially expand paths too.
    13251388 * @returns   pszFilename
    1326  * @param     pszFilename  Pointer to filename string.
     1389 * @param     pszFilename  Pointer to filename string. Not empty string!
     1390 *                         Much space to play with.
    13271391 */
    13281392char *fileNormalize(char *pszFilename)
     
    13301394    char *psz = pszFilename;
    13311395
     1396    /* correct slashes */
    13321397    while ((pszFilename = strchr(pszFilename, '//')) != NULL)
    13331398        *pszFilename++ = '\\';
    13341399
     1400    /* expand path? */
     1401    pszFilename = psz;
     1402    if (pszFilename[1] != ':')
     1403    {   /* relative path */
     1404        int     iSlash;
     1405        char    szFile[CCHMAXPATH];
     1406        char *  psz = szFile;
     1407
     1408        strcpy(szFile, pszFilename);
     1409        iSlash = *psz == '\\' ? 0 : cSlashes;
     1410        while (*psz != '\0')
     1411        {
     1412            if (*psz == '.' && psz[1] == '.'  && psz[2] == '\\')
     1413            {   /* up one directory */
     1414                if (iSlash > 0)
     1415                    iSlash--;
     1416                psz += 3;
     1417            }
     1418            else if (*psz == '.' && psz[1] == '\\')
     1419            {   /* no change */
     1420                psz += 2;
     1421            }
     1422            else
     1423            {   /* completed expantion! */
     1424                strncpy(pszFilename, szCurDir, aiSlashes[iSlash]+1);
     1425                strcpy(pszFilename + aiSlashes[iSlash]+1, psz);
     1426                break;
     1427            }
     1428        }
     1429    }
     1430    /* else: assume full path */
     1431
    13351432    return psz;
    13361433}
     1434
     1435
     1436/**
     1437 * Normalizes the path slashes for the filename. It will partially expand paths too.
     1438 * @returns   pszFilename
     1439 * @param     pszFilename  Pointer to filename string. Not empty string!
     1440 *                         Much space to play with.
     1441 * @param     pszBuffer    Pointer to output buffer.
     1442 */
     1443char *fileNormalize2(const char *pszFilename, char *pszBuffer)
     1444{
     1445    char    *psz = pszBuffer;
     1446
     1447    /* expand path? */
     1448    if (pszFilename[1] != ':')
     1449    {   /* relative path */
     1450        int     iSlash;
     1451
     1452        iSlash = *pszFilename == '\\' || *pszFilename == '/' ? 0 : cSlashes;
     1453        while (*pszFilename != '\0')
     1454        {
     1455            if (*pszFilename == '.' && pszFilename[1] == '.'  && (pszFilename[2] == '\\' || pszFilename[1] == '/'))
     1456            {   /* up one directory */
     1457                if (iSlash > 0)
     1458                    iSlash--;
     1459                pszFilename += 3;
     1460            }
     1461            else if (*pszFilename == '.' && (pszFilename[1] == '\\' || pszFilename[1] == '/'))
     1462            {   /* no change */
     1463                pszFilename += 2;
     1464            }
     1465            else
     1466            {   /* completed expantion! */
     1467                strncpy(pszBuffer, szCurDir, aiSlashes[iSlash]+1);
     1468                strcpy(pszBuffer + aiSlashes[iSlash]+1, pszFilename);
     1469                break;
     1470            }
     1471        }
     1472    }
     1473    /* else: assume full path */
     1474
     1475    /* correct slashes */
     1476    while ((pszBuffer = strchr(pszBuffer, '//')) != NULL)
     1477        *pszBuffer++ = '\\';
     1478
     1479    return psz;
     1480}
     1481
    13371482
    13381483/**
     
    15931738            else
    15941739                cfcNodes++;
    1595             _heap_check();
    15961740        }
    15971741
     
    16411785 * @parma     pszFilename  Filename to find.
    16421786 * @parma     pszBuffer    Ouput Buffer.
     1787 * @param     pOptions     Pointer to options struct.
    16431788 * @status    completely implemented.
    16441789 * @author    knut st. osmundsen
    16451790 * @remark    need substantial optimizations. 95% of execution is spend here.
    16461791 */
    1647 static char *pathlistFindFile(const char *pszPathList, const char *pszFilename, char *pszBuffer)
     1792static char *pathlistFindFile(const char *pszPathList, const char *pszFilename, char *pszBuffer, POPTIONS pOptions)
    16481793{
    16491794    const char *psz = pszPathList;
     
    16651810        {
    16661811            APIRET          rc;
    1667             char            szFile[CCHMAXPATH];
    16681812
    16691813            /* make search statment */
    1670             strncpy(szFile, psz, pszNext - psz);
    1671             szFile[pszNext - psz] = '\0';
    1672             if (szFile[pszNext - psz - 1] != '\\' && szFile[pszNext - psz - 1] != '/')
    1673                 strcpy(&szFile[pszNext - psz], "\\");
    1674             strcat(szFile, pszFilename);
    1675             strlwr(szFile); /* to speed up AVL tree search we'll lowercase all names. */
    1676             fileNormalize(szFile);
     1814            strncpy(pszBuffer, psz, pszNext - psz);
     1815            pszBuffer[pszNext - psz] = '\0';
     1816            if (pszBuffer[pszNext - psz - 1] != '\\' && pszBuffer[pszNext - psz - 1] != '/')
     1817                strcpy(&pszBuffer[pszNext - psz], "\\");
     1818            strcat(pszBuffer, pszFilename);
     1819            strlwr(pszBuffer); /* to speed up AVL tree search we'll lowercase all names. */
     1820            fileNormalize(pszBuffer);
    16771821
    16781822            /*
     
    16801824             *   Search cache first
    16811825             */
    1682             if (!filecacheFind(szFile))
     1826            if (!filecacheFind(pszBuffer))
    16831827            {
    16841828                char szDir[CCHMAXPATH];
    16851829
    1686                 filePathSlash(szFile, szDir);
    1687                 if (filecacheIsDirCached(szDir))
    1688                     rc = ERROR_FILE_NOT_FOUND;
    1689                 else
     1830                filePathSlash(pszBuffer, szDir);
     1831                if (!filecacheIsDirCached(szDir))
    16901832                {
    16911833                    /*
     
    16931835                     * add the directory to the cache and search it.
    16941836                     */
    1695                     if (fCacheSearchDirs && filecacheAddDir(szDir))
    1696                         rc = filecacheFind(szFile) ? NO_ERROR : ERROR_FILE_NOT_FOUND;
     1837                    if (pOptions->fCacheSearchDirs && filecacheAddDir(szDir))
     1838                    {
     1839                        if (filecacheFind(pszBuffer))
     1840                            return pszBuffer;
     1841                    }
    16971842                    else
    16981843                    {
     
    17001845
    17011846                        /* ask the OS */
    1702                         rc = DosQueryPathInfo(szFile, FIL_STANDARD, &fsts3, sizeof(fsts3));
     1847                        rc = DosQueryPathInfo(pszBuffer, FIL_STANDARD, &fsts3, sizeof(fsts3));
    17031848                        if (rc == NO_ERROR)
    17041849                        {   /* add file to cache. */
    1705                             filecacheAddFile(szFile);
     1850                            filecacheAddFile(pszBuffer);
     1851                            return pszBuffer;
    17061852                        }
    17071853                    }
     
    17091855            }
    17101856            else
    1711                 rc = NO_ERROR;
    1712 
    1713             /* did we find it? */
    1714             if (rc == NO_ERROR)
    1715             {
    1716                 strncpy(pszBuffer, psz, pszNext - psz);
    1717                 pszBuffer[pszNext - psz] = '\0';
    1718                 if (pszBuffer[pszNext - psz - 1] != '\\' && pszBuffer[pszNext - psz - 1] != '/')
    1719                     strcpy(&pszBuffer[pszNext - psz], "\\");
    1720                 strcat(pszBuffer, pszFilename);
    1721                 break;
    1722             }
     1857                return pszBuffer;
    17231858        }
    17241859
     
    17291864    }
    17301865
    1731     return *pszBuffer == '\0' ? NULL : pszBuffer;
     1866    return NULL;
    17321867}
    17331868
     
    19712106 * Appends a depend file to the internal file.
    19722107 */
    1973 static BOOL  depReadFile(const char *pszFilename)
     2108static BOOL  depReadFile(const char *pszFilename, POPTIONS pOptions)
    19742109{
    19752110    void *pvFile;
     
    20592194                psz = trim(psz);
    20602195                if (*psz != '\0')
    2061                     depAddDepend(pvRule, psz);
     2196                    depAddDepend(pvRule, psz, pOptions->fCheckCyclic);
    20622197            }
    20632198        }
     
    20812216    if (phFile != NULL)
    20822217    {
    2083         char     szBuffer[4096];
    2084         int      iBuffer = 0;
    2085         int      cch;
    2086         PDEPRULE pdep = pdepList;
    2087 
     2218        AVLENUMDATA EnumData;
     2219        PDEPRULE    pdep;
     2220        char        szBuffer[4096];
     2221        int         iBuffer = 0;
     2222        int         cch;
     2223
     2224        pdep = (PDEPRULE)(void*)AVLBeginEnumTree((PPAVLNODECORE)(void*)&pdepTree, &EnumData, TRUE);
    20882225        while (pdep != NULL)
    20892226        {
     
    21282265
    21292266            /* next rule */
    2130             pdep = pdep->pNext;
     2267            pdep = (PDEPRULE)(void*)AVLGetNextNode(&EnumData);
    21312268        }
    21322269
     
    21432280
    21442281/**
    2145  * Removes all entries in the list of dependencies. (pdepList)
     2282 * Removes all nodes in the tree of dependencies. (pdepTree)
    21462283 */
    21472284static void  depRemoveAll(void)
    21482285{
    2149     while (pdepList != NULL)
    2150     {
    2151         register PDEPRULE pdepToBeFree = pdepList;
    2152         /* next */
    2153         pdepList = pdepToBeFree->pNext;
    2154 
     2286    AVLENUMDATA EnumData;
     2287    PDEPRULE    pdep;
     2288
     2289    pdep = (PDEPRULE)(void*)AVLBeginEnumTree((PPAVLNODECORE)(void*)&pdepTree, &EnumData, TRUE);
     2290    while (pdep != NULL)
     2291    {
    21552292        /* free this */
    2156         if (pdepToBeFree->papszDep != NULL)
     2293        if (pdep->papszDep != NULL)
    21572294        {
    2158             char ** ppsz = pdepToBeFree->papszDep;
     2295            char ** ppsz = pdep->papszDep;
    21592296            while (*ppsz != NULL)
    21602297                free(*ppsz++);
    2161             free(pdepToBeFree->papszDep);
     2298            free(pdep->papszDep);
    21622299        }
    2163         free(pdepToBeFree);
    2164     }
     2300        free(pdep);
     2301
     2302        /* next */
     2303        pdep = (PDEPRULE)(void*)AVLGetNextNode(&EnumData);
     2304    }
     2305    pdepTree = NULL;
    21652306}
    21662307
     
    21792320{
    21802321    char     szRule[CCHMAXPATH*2];
    2181     PDEPRULE pdepPrev = NULL;
    2182     PDEPRULE pdep = pdepList;
    21832322    PDEPRULE pNew;
    21842323    int      cch;
     
    21992338    }
    22002339
    2201     /* find location */
    2202     while (pdep != NULL && stricmp(pdep->pszRule, szRule) < 0)
    2203     {
    2204         pdepPrev = pdep;
    2205         pdep = pdep->pNext;
    2206     }
    2207 
    2208     /* check if matching rule name */
    2209     if (pdep != NULL && stricmp(pdep->pszRule, szRule) == 0)
    2210         return NULL;
    22112340
    22122341    /*
     
    22162345    pNew = malloc(sizeof(DEPRULE) + cch + 1);
    22172346    if (pNew == NULL)
     2347    {
     2348        fprintf(stderr, "error: out of memory. (line=%d)\n", __LINE__);
    22182349        return NULL;
     2350    }
    22192351    pNew->pszRule = (char*)(void*)(pNew + 1);
    22202352    strcpy(pNew->pszRule, szRule);
    22212353    pNew->cDeps = 0;
    22222354    pNew->papszDep = NULL;
    2223 
    2224     /* link in module (before pdep) */
    2225     pNew->pNext = pdep;
    2226     if (pdepPrev == NULL)
    2227         pdepList = pNew;
    2228     else
    2229         pdepPrev->pNext = pNew;
    2230 
    2231     _heap_check();
     2355    pNew->avlCore.Key = pNew->pszRule;
     2356
     2357    /* Insert rule */
     2358    if (!AVLInsert((PPAVLNODECORE)(void*)&pdepTree, &pNew->avlCore))
     2359    {   /* rule existed - return NULL */
     2360        free(pNew);
     2361        return NULL;
     2362    }
     2363
    22322364    return pNew;
    22332365}
     
    22372369/**
    22382370 * Adds a dependant to a rule.
    2239  * @returns   Successindicator.
    2240  * @param     pvRule   Rule handle.
    2241  * @param     pszDep   Pointer to dependant name
    2242  */
    2243 static BOOL  depAddDepend(void *pvRule, const char *pszDep)
     2371 * @returns   Successindicator. TRUE = success.
     2372 *            FALSE = cyclic or out of memory.
     2373 * @param     pvRule        Rule handle.
     2374 * @param     pszDep        Pointer to dependant name
     2375 * @param     fCheckCyclic  When set we'll check that we're not creating an cyclic dependency.
     2376 */
     2377static BOOL  depAddDepend(void *pvRule, const char *pszDep, BOOL fCheckCyclic)
    22442378{
    22452379    PDEPRULE pdep = (PDEPRULE)pvRule;
     2380
     2381    if (fCheckCyclic && depCheckCyclic(pdep, pszDep))
     2382    {
     2383        fprintf(stderr, "warning: Cylic dependancy caused us to ignore '%s' in rule '%s'.\n",
     2384                pszDep, pdep->pszRule);
     2385        return FALSE;
     2386    }
    22462387
    22472388    /* allocate more array space */
     
    22522393        {
    22532394            pdep->cDeps = 0;
     2395            fprintf(stderr, "error: out of memory, (line=%d)\n", __LINE__);
    22542396            return FALSE;
    22552397        }
     
    22582400    /* allocate string space and copy pszDep */
    22592401    if ((pdep->papszDep[pdep->cDeps] = malloc(strlen(pszDep) + 1)) == NULL)
     2402    {
     2403        fprintf(stderr, "error: out of memory, (line=%d)\n", __LINE__);
    22602404        return FALSE;
     2405    }
    22612406    strcpy(pdep->papszDep[pdep->cDeps], pszDep);
    22622407
     
    22652410
    22662411    /* successful! */
    2267     _heap_check();
    22682412    return TRUE;
    22692413}
    22702414
     2415
     2416/**
     2417 * Checks if adding this dependent will create a cylic dependency.
     2418 * @returns   TRUE: Cyclic.
     2419 *            FALSE: Non-cylic.
     2420 * @param     pdepRule  Rule pszDep is to be inserted in.
     2421 * @param     pszDep    Depend name.
     2422 */
     2423static BOOL depCheckCyclic(PDEPRULE pdepRule, const char *pszDep)
     2424{
     2425    #define DEPTH 32
     2426    char *   pszRule = pdepRule->pszRule;
     2427    char **  appsz[DEPTH];
     2428    PDEPRULE pdep;
     2429    int      i;
     2430
     2431    /* find rule for the dep. */
     2432    if ((pdep = (PDEPRULE)(void*)AVLGet((PPAVLNODECORE)(void*)&pdepTree, pszDep)) == NULL
     2433        || pdep->papszDep == NULL)
     2434        return FALSE; /* no rule, or no dependents, not cyclic */
     2435
     2436    i = 0;
     2437    appsz[0] = pdep->papszDep;
     2438    while (i >= 0)
     2439    {
     2440        register char **  ppsz = appsz[i];
     2441
     2442        while (*ppsz != NULL)
     2443        {
     2444            /* check if equal to the main rule */
     2445            if (strcmp(pszRule, *ppsz) == 0)
     2446                return TRUE;
     2447
     2448            /* push onto stack (ppsz is incremented in this test!) */
     2449            if ((pdep = (PDEPRULE)(void*)AVLGet((PPAVLNODECORE)(void*)&pdepTree, *ppsz++)) != NULL
     2450                && pdep->papszDep != NULL)
     2451            {
     2452                appsz[i++] = ppsz; /* save next */
     2453                ppsz = pdep->papszDep; /* start processing new node */
     2454            }
     2455        }
     2456
     2457        /* pop stack */
     2458        i--;
     2459    }
     2460
     2461    return FALSE;
     2462}
    22712463
    22722464
     
    22752467 */
    22762468#include <os2.h>
    2277 
    2278 
    2279 
     2469#ifdef OLEMANN
     2470#include "olemann.h"
     2471#endif
     2472
     2473
     2474
Note: See TracChangeset for help on using the changeset viewer.