Ignore:
Timestamp:
Sep 7, 2001, 12:26:42 PM (24 years ago)
Author:
bird
Message:

dll to module conversion.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/tools/database/StateUpd.cpp

    r6665 r6677  
    1 /* $Id: StateUpd.cpp,v 1.37 2001-09-06 03:17:37 bird Exp $
     1/* $Id: StateUpd.cpp,v 1.38 2001-09-07 10:24:06 bird Exp $
    22 *
    33 * StateUpd - Scans source files for API functions and imports data on them.
     
    88
    99/*******************************************************************************
    10 *   Header Files                                                               *
     10*   Defined Constants And Macros                                               *
    1111*******************************************************************************/
     12#define DEBUGLOG    1                   /* enables debug logging. */
     13#ifdef DEBUGLOG
     14#define logprintf(a) fprintf a
     15#else
     16#define logprintf(a) ((int)0)
     17#endif
     18
    1219#define INCL_DOSFILEMGR
    1320#define INCL_DOSERRORS
    1421#define INCL_DOSMISC
    1522#define INCL_DOSPROCESS
     23
     24
     25/*******************************************************************************
     26*   Header Files                                                               *
     27*******************************************************************************/
    1628#include <os2.h>
    1729#include <malloc.h>
     
    2436#include "db.h"
    2537
    26 
    27 
    2838/*******************************************************************************
    2939*   Global Variables                                                           *
    3040*******************************************************************************/
     41#ifdef DEBUGLOG
    3142static FILE  *phLog = NULL;
     43#endif
    3244static FILE  *phSignal = NULL;
    3345
     
    4658static void closeLogs(void);
    4759static unsigned long processDir(const char *pszDirOrFile, POPTIONS pOptions);
    48 static unsigned long processFile(const char *pszFilename, POPTIONS pOptions);
    49 static unsigned long processModuleHeader(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);
     60static unsigned long processFile(const char *pszFilename, POPTIONS pOptions, BOOL fHeader);
     61static unsigned long processFileHeader(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);
    5062static unsigned long processDesignNote(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);
    51 static unsigned long processAPI(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);
     63static unsigned long processFunction(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);
    5264static unsigned long analyseFnHdr(PFNDESC pFnDesc, char **papszLines, int i, const char *pszFilename, POPTIONS pOptions);
    5365static unsigned long analyseFnDcl(PFNDESC pFnDesc, char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);
    5466static unsigned long analyseFnDcl2(PFNDESC pFnDesc, char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);
     67static void  logFunction(PFNDESC pFnDesc);
     68static char *ResolvSourceFile(char *pszFileObj, char **papszDirs);
    5569static char *SDSCopyTextUntilNextTag(char *pszTarget, BOOL fHTML, int iStart, int iEnd, char **papszLines, const char *pszStart = NULL);
    5670static char *CommonCopyTextUntilNextTag(char *pszTarget, BOOL fHTML, int iStart, int iEnd, char **papszLines, const char *pszStart = NULL);
    5771static BOOL  isFunction(char **papszLines, int i, POPTIONS pOptions);
    5872static BOOL  isDesignNote(char **papszLines, int i, POPTIONS pOptions);
     73static BOOL  isClass(char **papszLines, int i, POPTIONS pOptions);
    5974static long _System dbNotUpdatedCallBack(const char *pszValue, const char *pszFieldName, void *pvUser);
    6075static char *skipInsignificantChars(char **papszLines, int &i, char *psz);
     
    7489static char *skipBackwards(const char *pszStopAt, const char *pszFrom, int &iLine, char **papszLines);
    7590static int   findStrLine(const char *psz, int iStart, int iEnd, char **papszLines);
     91static void *textbufferCreate(const char *pszFilename);
     92static char *textbufferGetNextLine(void *pvBuffer, void **ppv, char *pszLineBuffer, int cchLineBuffer);
     93static char *textbufferNextLine(void *pvBuffer, register char *psz);
     94static void  textbufferDestroy(void *pvBuffer);
     95static signed long fsize(FILE *phFile);
     96static char *fileNameNoExt(const char *pszFilename, char *pszBuffer);
    7697
    7798
     
    87108    BOOL           fFatal = FALSE;
    88109    unsigned long  ulRc = 0;
    89     char           szDLLName[64];
    90     OPTIONS        options = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, &szDLLName[0], -1};
     110    char           szModName[64];
     111    char *         apszDirs[2] = {".", NULL};
     112    OPTIONS        options =
     113    {   FALSE,                          /* fIntegrityBefore  */
     114        FALSE,                          /* fIntegrityAfter;  */
     115        FALSE,                          /* fIntegrityOnly;   */
     116        FALSE,                          /* fRecursive;       */
     117        FALSE,                          /* fOld;             */
     118        FALSE,                          /* fOS2;             */
     119        FALSE,                          /* fCOMCTL32;        */
     120        FALSE,                          /* fVERSION;         */
     121        &szModName[0],                  /* pszModName;       */
     122        ' ',                            /* chModType;        */
     123        -1,                             /* lModRefcode;      */
     124        -1,                             /* lFileRefcode;     */
     125        &apszDirs[0]                    /* apszDirs;         */
     126    };
    91127    unsigned long  ulRc2;
    92128    char          *pszErrorDesc = NULL;
     
    101137    /*DosSetPriority(PRTYS_PROCESSTREE, PRTYC_REGULAR, 1, 0);*/
    102138
    103     /* get dll name from directory */
     139    /* get module name from directory */
    104140    ul1 = ul2 = 0;
    105141    DosQueryCurrentDisk(&ul1, &ul2);
    106     ul2 = sizeof(szDLLName);
    107     DosQueryCurrentDir(ul1, &szDLLName[0], &ul2);
     142    ul2 = sizeof(szModName);
     143    DosQueryCurrentDir(ul1, &szModName[0], &ul2);
    108144    if (ul2 != 0)
    109145    {
    110         if (szDLLName[ul2-1] == '\\' || szDLLName[ul2-1] == '/')
    111             szDLLName[--ul2] = '\0';
     146        if (szModName[ul2-1] == '\\' || szModName[ul2-1] == '/')
     147            szModName[--ul2] = '\0';
    112148        ul1 = ul2;
    113         while (ul1 != 0 && szDLLName[ul1-1] != '\\' && szDLLName[ul1-1] != '/')
     149        while (ul1 != 0 && szModName[ul1-1] != '\\' && szModName[ul1-1] != '/')
    114150            ul1--;
    115151        if (ul1 != 0)
    116             options.pszDLLName = &szDLLName[ul1];
     152            options.pszModName = &szModName[ul1];
    117153    }
    118154    else
    119         szDLLName[0] = '\0';
     155        szModName[0] = '\0';
    120156
    121157
     
    127163    *           -io              Integrity check only.
    128164    *           -s               Scan subdirectories.
    129     *           -Old <[+]|->     Old API Style.
    130165    *           -OS2<[+]|->      Removes 'OS2'-prefix from function name.
    131166    *           -COMCTL32<[+]|-> Removes 'COMCTL32'-prefix from function name.
    132167    *           -VERSION<[+]|->  Removes 'VERSION'-prefix from function name.
    133     *           -Dll:<dllname>   Name of the dll being processed.
     168    *           -Mod:<modname>   Name of the module being processed.
     169    *           -Type:<modtype>  Module type. default API or whatever is in DB.
    134170    *           -d:<dbname>      Database name
    135171    *           -p:<passwd>      Password
     
    147183                case 'D':
    148184                    if (strnicmp(&argv[argi][1], "dll:", 4) == 0 )
    149                         options.pszDLLName = &argv[argi][5];
     185                        options.pszModName = &argv[argi][5];
    150186                    else
    151187                    {
     
    157193                    break;
    158194
     195                case '-':
    159196                case 'h':
    160197                case 'H':
     
    192229                    }
    193230                    break;
     231
     232                case 'm':
     233                case 'M':
     234                    if (strchr(&argv[argi][1], ':'))
     235                        options.pszModName = strchr(&argv[argi][1], ':') + 1;
     236                    else
     237                    {
     238                        fFatal = TRUE;
     239                        fprintf(stderr, "warning: option '-mod:' requires a module name.\n");
     240                    }
     241                    break;
     242
    194243
    195244                case 'o':
     
    217266                case 'S':
    218267                    options.fRecursive = TRUE;
    219                     fprintf(stderr, "Warning: -s processes subdirs of source for one DLL\n");
     268                    fprintf(stderr, "Warning: -s processes subdirs of source for one module\n");
    220269                    break;
    221270
     
    228277                    break;
    229278
     279                case 't':
     280                case 'T':
     281                    if (strchr(&argv[argi][1], ':'))
     282                    {
     283                        char ch = *(strchr(&argv[argi][1], ':') + 1);
     284                        if (strchr("AIST", ch))
     285                            options.chModType = ch;
     286                        else
     287                        {
     288                            fFatal = TRUE;
     289                            fprintf(stderr, "warning: option '-type:' requires type char.\n");
     290                        }
     291                    }
     292                    else
     293                    {
     294                        fFatal = TRUE;
     295                        fprintf(stderr, "warning: option '-type:' requires type char.\n");
     296                    }
     297                    break;
     298
    230299                default:
    231300                    fprintf(stderr, "incorrect parameter. (argi=%d, argv[argi]=%s)\n", argi, argv[argi]);
     
    234303            }
    235304        }
     305        else if (argv[argi][0] == '@')
     306        {   /*
     307             * Parameter file (debugger parameter length restrictions led to this):
     308             *    Create a textbuffer.
     309             *    Parse the file and create a new parameter vector.
     310             *    Set argv to the new parameter vector, argi to 0 and argc to
     311             *    the parameter count.
     312             *    Restrictions: Parameters enclosed in "" is not implemented.
     313             *                  No commandline parameters are processed after the @file
     314             */
     315            char *pszBuffer = (char*)textbufferCreate(&argv[argi][1]); /* !ASSUMS! that pvBuffer is the file string! */
     316            if (pszBuffer != NULL)
     317            {
     318                char **apszArgs = NULL;
     319                char *psz = pszBuffer;
     320                int  i = 0;
     321
     322                while (*psz != '\0')
     323                {
     324                    /* find end of parameter word */
     325                    char *pszEnd = psz + 1;
     326                    char  ch = *pszEnd;
     327                    while (ch != ' ' && ch != '\t' && ch != '\n' && ch != '\r' && ch != '\0')
     328                        ch = *++pszEnd;
     329
     330                    /* allocate more arg array space? */
     331                    if ((i % 512) == 0)
     332                    {
     333                        apszArgs = (char**)realloc(apszArgs, sizeof(char*) * (514 + i));
     334                        if (apszArgs == NULL)
     335                        {
     336                            fprintf(stderr, "error: out of memory. (line=%d)\n", __LINE__);
     337                            return -8;
     338                        }
     339                    }
     340                    *pszEnd = '\0';
     341                    apszArgs[i++] = psz;
     342
     343                    /* next */
     344                    psz = pszEnd + 1;
     345                    ch = *psz;
     346                    while (ch == ' ' || ch == '\t' || ch == '\n' || ch == '\r')
     347                        ch = *++psz;
     348                }
     349
     350                argc = i;
     351                argi = 0;
     352                argv = apszArgs;
     353                apszArgs[argc] = NULL;
     354                continue;
     355            }
     356            else
     357            {
     358                fprintf(stderr, "error: could not open parameter file\n");
     359                return -1;
     360            }
     361            break;
     362        }
    236363        else
    237364            break; /* files has started */
     
    266393        }
    267394
     395
    268396        if (!options.fIntegrityOnly)
    269397        {
    270             /* find dll */
    271             options.lDllRefcode = dbGetDll(options.pszDLLName);
    272             fprintf(phLog, "DLL: refcode=%d, name=%s\n", options.lDllRefcode, options.pszDLLName);
    273             if (options.lDllRefcode >= 0)
     398            /* add/update module */
     399            if (options.chModType != ' ' && options.pszModName)
     400                dbCheckInsertModule(options.pszModName, options.chModType);
     401
     402            /* find module */
     403            options.lModRefcode = dbGetModule(options.pszModName);
     404            logprintf((phLog, "Module: refcode=%d, name=%s\n", options.lModRefcode, options.pszModName));
     405            if (options.lModRefcode >= 0)
    274406            {
    275407                /* processing */
     
    277409                    ulRc = processDir(".", &options);
    278410                else
    279                     while (argv[argi] != NULL)
     411                    while (argi < argc)
    280412                    {
    281                         ulRc += processDir(argv[argi], &options);
     413                        char *  pszDirOrFile = argv[argi];
     414                        int     cchDirOrFile = strlen(pszDirOrFile);
     415
     416                        if (cchDirOrFile > 4 && !stricmp(pszDirOrFile + cchDirOrFile - 4, ".obj") ) /* check for .obj */
     417                        {
     418                            pszDirOrFile = ResolvSourceFile(pszDirOrFile, options.papszDirs);
     419                            if (!pszDirOrFile)
     420                            {
     421                                /*
     422                                 * Ignore dllentry.
     423                                 */
     424                                if (!stristr(argv[argi], "dllentry"))
     425                                {
     426                                    fprintf(phSignal, "%s: Failed to resolve source file\n", argv[argi]);
     427                                    ulRc += 0x00010000;
     428                                }
     429                                argi++;
     430                                break;
     431                            }
     432                        }
     433                        ulRc += processDir(pszDirOrFile, &options);
    282434                        argi++;
    283435                    }
     
    309461            }
    310462            else
    311             {   /* failed to find dll - concidered nearly fatal. */
    312                 fprintf(phSignal, "-,-: failed to find dll (%s)!\n\t%s\n",
    313                         options.pszDLLName ? options.pszDLLName : "<NULL>",
     463            {   /* failed to find module - concidered nearly fatal. */
     464                fprintf(phSignal, "-,-: failed to find module (%s)!\n\t%s\n",
     465                        options.pszModName ? options.pszModName : "<NULL>",
    314466                        dbGetLastErrorDesc());
    315467                ulRc++;
     
    320472        if (!options.fIntegrityOnly)
    321473        {
    322             cUpdated    = dbGetNumberOfUpdatedFunction(options.lDllRefcode);
    323             cAll        = dbCountFunctionInDll(options.lDllRefcode, FALSE);
    324             cNotAliased = dbCountFunctionInDll(options.lDllRefcode, TRUE);
     474            cUpdated    = dbGetNumberOfUpdatedFunction(options.lModRefcode);
     475            cAll        = dbCountFunctionInModule(options.lModRefcode, FALSE);
     476            cNotAliased = dbCountFunctionInModule(options.lModRefcode, TRUE);
    325477            if (cNotAliased > cUpdated)
    326478            {
     
    329481                ulRc += 0x00010000;
    330482            }
    331             fprintf(phLog, "-------------------------------------------------\n");
    332             fprintf(phLog, "-------- Functions which was not updated --------\n");
    333             dbGetNotUpdatedFunction(options.lDllRefcode, dbNotUpdatedCallBack);
    334             fprintf(phLog, "-------------------------------------------------\n");
    335             fprintf(phLog, "-------------------------------------------------\n\n");
    336             fprintf(phLog,"Number of function in this DLL:        %4ld (%ld)\n", cAll, cNotAliased);
    337             fprintf(phLog,"Number of successfully processed APIs: %4ld (%ld)\n", (long)(0x0000FFFF & ulRc), cUpdated);
    338         }
    339         fprintf(phLog,"Number of signals:                     %4ld\n", (long)(ulRc >> 16));
     483            logprintf((phLog, "------------------------------------------------------\n"));
     484            logprintf((phLog, "-------- Functions which was not updated -------------\n"));
     485            dbGetNotUpdatedFunction(options.lModRefcode, dbNotUpdatedCallBack);
     486            logprintf((phLog, "------------------------------------------------------\n"));
     487            logprintf((phLog, "------------------------------------------------------\n\n"));
     488            logprintf((phLog,"Number of function in this module:          %4ld (%ld)\n", cAll, cNotAliased));
     489            logprintf((phLog,"Number of successfully processed functions: %4ld (%ld)\n", (long)(0x0000FFFF & ulRc), cUpdated));
     490        }
     491        logprintf((phLog,    "Number of signals:                          %4ld\n", (long)(ulRc >> 16)));
    340492
    341493        /* close the logs */
     
    348500        if (!options.fIntegrityOnly)
    349501        {
    350             fprintf(stdout,"Number of function in this DLL:        %4ld (%ld)\n", cAll, cNotAliased);
    351             fprintf(stdout,"Number of successfully processed APIs: %4ld (%ld)\n", (long)(0x0000FFFF & ulRc), cUpdated);
    352         }
    353         fprintf(stdout,"Number of signals:                     %4ld\n", (long)(ulRc >> 16));
     502            fprintf(stdout,"Number of function in this module:          %4ld (%ld)\n", cAll, cNotAliased);
     503            fprintf(stdout,"Number of successfully processed functions: %4ld (%ld)\n", (long)(0x0000FFFF & ulRc), cUpdated);
     504        }
     505        fprintf(stdout,    "Number of signals:                          %4ld\n", (long)(ulRc >> 16));
    354506        if ((int)(ulRc >> 16) > 0)
    355507            fprintf(stderr, "Check signal file 'Signals.Log'.\n");
     
    376528           "    -io           Integrity check only.         default: disabled\n"
    377529           "    -s            Scan subdirectories.          default: disabled\n"
    378            "    -Old          Use old API style.            default: disabled\n"
    379530           "    -OS2          Ignore 'OS2'-prefix on APIs.  default: disabled\n"
    380            "    -Dll:<dllname> Name of the dll.             default: currentdirname\n"
     531           "    -Mod:<modname> Name of the module.          default: currentdirname\n"
     532           "    -Type:<type>  Module type. AIST.            default: read database\n"
    381533           "    -h:<hostname> Database server hostname.     default: localhost\n"
    382534           "    -u:<username> Username on the server.       default: root\n"
     
    402554static void openLogs(void)
    403555{
     556    #ifdef DEBUGLOG
    404557    if (phLog == NULL)
    405558    {
     
    411564        }
    412565    }
     566    #endif
    413567
    414568    if (phSignal == NULL)
     
    429583static void closeLogs(void)
    430584{
     585    #ifdef DEBUGLOG
    431586    if (phLog != stderr && phLog != NULL)
    432587        fclose(phLog);
     588    #endif
    433589    if (phSignal != stdout && phSignal != NULL)
    434590    {
     
    473629    rc = DosQueryPathInfo(pszDirOrFile, FIL_STANDARD, &fs , sizeof(fs));
    474630    fFile = rc == NO_ERROR && (fs.attrFile & FILE_DIRECTORY) != FILE_DIRECTORY;
     631    if (!fFile)
     632        fFile = strpbrk(pszDirOrFile, "*?") != NULL;
    475633
    476634    /* 0. */
     
    510668        char *psz = strrchr(&ffb.achName[0], '.');
    511669        if (psz != NULL && (!stricmp(psz, ".cpp") || !stricmp(psz, ".c")))
    512             ulRc += processFile(strcat(strcat(strcpy(&szFileSpec[0], pszDir), "\\"), &ffb.achName[0]), pOptions);
     670            ulRc += processFile(strcat(strcat(strcpy(&szFileSpec[0], pszDir), "\\"), &ffb.achName[0]), pOptions, FALSE);
     671        else if (psz != NULL && (!stricmp(psz, ".h") || !stricmp(psz, ".hpp")))
     672            ulRc += processFile(strcat(strcat(strcpy(&szFileSpec[0], pszDir), "\\"), &ffb.achName[0]), pOptions, TRUE);
    513673
    514674        /* next */
     
    551711/**
    552712 * Processes a file.
    553  * @returns   high word = number of signals
    554  *            low  word = number of APIs processed. (1 or 0).
    555  * @param     pszFilename  Filename
    556  * @param     pOptions  Pointer to options.
     713 * @returns high word = number of signals
     714 *          low  word = number of APIs processed. (1 or 0).
     715 * @param   pszFilename Filename
     716 * @param   pOptions    Pointer to options.
     717 * @param   fHeader     Flags if we're processing a header file or not.
    557718 * @sketch     1. read file into memory.
    558719 *             2. create line array.
    559720 *            (3. simple preprocessing - TODO)
    560  *             4. process module header.
     721 *             4. process file header.
    561722 *             5. scan thru the line array, looking for APIs and designnotes.
    562723 *                5b. when API is found, process it.
    563724 *                5c. when designnote found, process it.
    564725 */
    565 static unsigned long processFile(const char *pszFilename, POPTIONS pOptions)
     726static unsigned long processFile(const char *pszFilename, POPTIONS pOptions, BOOL fHeader)
    566727{
    567728    unsigned long  cSignals = 0;
     
    569730    char          *pszFile;
    570731
    571     fprintf(phLog, "Processing '%s':\n", pszFilename);
    572     /* 1.*/
     732    logprintf((phLog, "Processing '%s':\n", pszFilename));
     733
     734    /*
     735     * (1) Read file into memory
     736     */
    573737    pszFile = readFileIntoMemory(pszFilename);
    574738    if (pszFile != NULL)
     
    576740        char **papszLines;
    577741
    578         /* 2.*/
     742        /*
     743         * (2) Create line array.
     744         */
    579745        papszLines = createLineArray(pszFile);
    580746        if (papszLines != NULL)
     
    583749            int i = 0;
    584750
    585             /* 3. - TODO */
    586 
    587             /* 4. */
    588             ulRc = processModuleHeader(papszLines, i, i, pszFilename, pOptions);
     751            /*
     752             * 3. Simple preprocessing - TODO
     753             */
     754
     755
     756            /*
     757             * (4) Process the file header.
     758             */
     759            ulRc = processFileHeader(papszLines, i, i, pszFilename, pOptions);
    589760            cSignals += ulRc >> 16;
    590761            if (ulRc & 0x0000ffff)
    591762            {
    592                 /* 4b.
    593                  * Remove Design notes.
     763                /*
     764                 * (4b) Remove Design notes.
    594765                 */
    595                 pOptions->lSeqFile = 0;
    596766                if (!dbRemoveDesignNotes(pOptions->lFileRefcode))
    597767                {
     
    602772
    603773
    604                 /* 5.*/
     774                /*
     775                 * (5) The scan loop.
     776                 */
    605777                while (papszLines[i] != NULL)
    606778                {
     779                    /*
     780                     * (5b) Function.
     781                     */
    607782                    if (isFunction(papszLines, i, pOptions))
    608783                    {
    609                         ulRc = processAPI(papszLines, i, i, pszFilename, pOptions);
     784                        ulRc = processFunction(papszLines, i, i, pszFilename, pOptions);
    610785                        cAPIs += 0x0000ffff & ulRc;
    611786                        cSignals += ulRc >> 16;
    612787                    }
    613                     else
     788                    /*
     789                     * (5c) Design note.
     790                     */
     791                    else if (isDesignNote(papszLines, i, pOptions))
    614792                    {
    615                         if (isDesignNote(papszLines, i, pOptions))
    616                         {
    617                             ulRc = processDesignNote(papszLines, i, i, pszFilename, pOptions);
    618                             cSignals += ulRc >> 16;
    619                         }
     793                        ulRc = processDesignNote(papszLines, i, i, pszFilename, pOptions);
     794                        cSignals += ulRc >> 16;
     795                    }
     796                    /*
     797                     * (5d) Class detection (experimental)
     798                     */
     799                    #ifdef DEBUGLOG
     800                    else if (isClass(papszLines, i, pOptions))
     801                    {
     802                        logprintf((phLog, "Found class at line %d. %s\n", i, papszLines[i]));
    620803                        i++;
    621804                    }
    622                 }
    623             }
    624 
     805                    #endif
     806                    /*
     807                     * Nothing.
     808                     */
     809                    else
     810                        i++;
     811                } /* while - scan loop */
     812            }
     813
     814            /*
     815             * Cleanup.
     816             */
    625817            free(papszLines);
    626818        }
     
    637829        cSignals++;
    638830    }
    639     fprintf(phLog, "Processing of '%s' is completed.\n\n", pszFilename);
    640 
     831    logprintf((phLog, "Processing of '%s' is completed.\n\n", pszFilename));
     832
     833    fHeader = fHeader;
    641834
    642835    return (unsigned long)((cSignals << 16) | cAPIs);
     
    645838
    646839/**
    647  * Processes an module header and other file information.
     840 * Processes an file header and other file information.
    648841 * @returns     high word = number of signals.
    649842 *              low  word = Success indicator (TRUE / FALSE).
     
    655848 * @sketch      Extract module information if any....
    656849 */
    657 static unsigned long processModuleHeader(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions)
    658 {
    659     char    szDescription[10240];       /* File description buffer. */
    660     char    szId[128];                  /* CVS Id keyword buffer. */
    661     char *  psz, *psz2;
     850static unsigned long processFileHeader(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions)
     851{
     852    char            szDescription[10240];       /* File description buffer. */
     853    char            szId[128];                  /* CVS Id keyword buffer. */
     854    char *          psz, *psz2;
    662855    const char *    pszDBFilename;
    663856    char *          pszLastDateTime = NULL;
     
    783976         * Insert or update the database.
    784977         */
    785         if (dbInsertUpdateFile((unsigned short)pOptions->lDllRefcode, pszDBFilename,
     978        if (dbInsertUpdateFile((unsigned short)pOptions->lModRefcode, pszDBFilename,
    786979                               &szDescription[0], pszLastDateTime, lLastAuthor, pszRevision))
    787980        {
     
    789982             * Get file refcode.
    790983             */
    791             pOptions->lFileRefcode = dbFindFile(pOptions->lDllRefcode, pszDBFilename);
     984            pOptions->lFileRefcode = dbFindFile(pOptions->lModRefcode, pszDBFilename);
    792985            if (pOptions->lFileRefcode < 0)
    793986            {
     
    9331126             * Add the note.
    9341127             */
    935             if (!dbAddDesignNote(pOptions->lDllRefcode, pOptions->lFileRefcode,
     1128            if (!dbAddDesignNote(pOptions->lModRefcode, pOptions->lFileRefcode,
    9361129                                 pszTitle, psz,
    9371130                                 lLevel, lSeqNbr, lSeqNbrNote++, i + 1, lLevel > 0, &lRefCode))
     
    9701163
    9711164/**
    972  * Processes an API function.
     1165 * Processes an function.
    9731166 * @returns   high word = number of signals
    9741167 *            low  word = number of APIs processed. (1 or 0).
     
    9791172 * @param     pOptions  Pointer to options.
    9801173 */
    981 static unsigned long processAPI(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions)
     1174static unsigned long processFunction(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions)
    9821175{
    9831176    unsigned long ulRc;
     
    9991192     */
    10001193
    1001     /* 1.*/
     1194    /*
     1195     * (1) Analyse function declaration.
     1196     */
    10021197    ulRc = analyseFnDcl(&FnDesc, papszLines, i, iRet, pszFilename, pOptions);
    10031198    if (0x0000ffff & ulRc) /* if low word is 0 the fatal */
    10041199    {
    1005         unsigned long ulRcTmp;
    1006         //char szErrorDesc[2113]; /* due to some limitation in the latest EMX release size is 2112 and not 4096 as initially implemented. */
    1007         char  *pszErrorDesc = (char*)malloc(20480);
    1008 
    1009         /* 2.*/
     1200        unsigned long   ulRcTmp;
     1201        char  *         pszErrorDesc = (char*)malloc(20480);
     1202
     1203        /*
     1204         * (2) Analyse function header.
     1205         */
    10101206        ulRcTmp = analyseFnHdr(&FnDesc, papszLines, i, pszFilename, pOptions);
    10111207        if (ulRcTmp == ~0UL) /* check for fatal error */
     1208        {
     1209            free(pszErrorDesc);
    10121210            return (0xffff0000UL & ulRc) + 0x00010000UL;
     1211        }
    10131212        ulRc += 0xffff0000UL & ulRcTmp;
    10141213
    1015         /* 3.*/
    1016         fprintf(phLog, "Name:      '%s'  (refcodes=", FnDesc.pszName);
    1017         for (j = 0; j < FnDesc.cRefCodes; j++)
    1018             fprintf(phLog, j > 0 ? ", %ld" : "%ld", FnDesc.alRefCode[j]);
    1019         fprintf(phLog, ")\n");
    1020         fprintf(phLog, "  Returns: '%s'\n", FnDesc.pszReturnType != NULL ? FnDesc.pszReturnType : "<missing>");
    1021         fprintf(phLog, "  cParams: %2d\n", FnDesc.cParams);
    1022         for (j = 0; j < FnDesc.cParams; j++)
    1023             fprintf(phLog, "  Param %2d: type '%s' %*s name '%s' description: %s\n", j, FnDesc.apszParamType[j],
    1024                     max((int)(15 - strlen(FnDesc.apszParamType[j])), 0), "", FnDesc.apszParamName[j],
    1025                     FnDesc.apszParamDesc[j] != NULL ?  FnDesc.apszParamDesc[j] : "(null)");
    1026         fprintf(phLog, "  Status:   %ld - '%s'\n", FnDesc.lStatus, FnDesc.pszStatus != NULL ? FnDesc.pszStatus : "<missing>");
    1027         fprintf(phLog, "  cAuthors: %2d\n", FnDesc.cAuthors);
    1028         for (j = 0; j < FnDesc.cAuthors; j++)
    1029             fprintf(phLog, "  Author %d: '%s'  (refcode=%ld)\n", j, FnDesc.apszAuthor[j], FnDesc.alAuthorRefCode[j]);
    1030 
    1031         fprintf(phLog, "  Description: %s\n", FnDesc.pszDescription != NULL ? FnDesc.pszDescription : "(null)");
    1032         fprintf(phLog, "  Remark:      %s\n", FnDesc.pszRemark != NULL ? FnDesc.pszRemark : "(null)");
    1033         fprintf(phLog, "  Return Desc: %s\n", FnDesc.pszReturnDesc != NULL ? FnDesc.pszReturnDesc : "(null)");
    1034         fprintf(phLog, "  Sketch:      %s\n", FnDesc.pszSketch != NULL ? FnDesc.pszSketch : "(null)");
    1035         fprintf(phLog, "  Equiv:       %s\n", FnDesc.pszEquiv != NULL ? FnDesc.pszEquiv : "(null)");
    1036         fprintf(phLog, "  Time:        %s\n", FnDesc.pszTime != NULL ? FnDesc.pszTime : "(null)");
    1037         fprintf(phLog, "------------\n");
    1038 
    1039         /* 4.*/
    1040         ulRcTmp = dbUpdateFunction(&FnDesc, pOptions->lDllRefcode, pszErrorDesc);
     1214        /*
     1215         * (3) Log data (for debug purpose).
     1216         */
     1217        logFunction(&FnDesc);
     1218
     1219        /*
     1220         * (4) Update database.
     1221         */
     1222        ulRcTmp = dbUpdateFunction(&FnDesc, pOptions->lModRefcode, pszErrorDesc);
    10411223        if (ulRcTmp != 0)
    10421224        {
     
    10641246                                  const char *pszFilename, POPTIONS pOptions)
    10651247{
    1066     static long     lPrevFnDll = -1L; /* fix for duplicate dlls */
    10671248    unsigned long   ulRc;
    10681249    FNFINDBUF       FnFindBuf;
     
    10701251
    10711252    /* brief algorithm:
    1072      * 1. read function declaration using analyseFnDcl2.
    1073      * 2. apply name rules.
    1074      * 3. do a database lookup on the name.
    1075      *  3b. if more that one match, write a signal. (TODO: a simple fix is done, but there are holes.)
     1253     * 1. Read function declaration using analyseFnDcl2.
     1254     * 2. Apply name rules.
     1255     * 3. Do a database lookup on the name.
     1256     *  3b. If more that one match, write a signal. (TODO: a simple fix is done, but there are holes.)
     1257     * 4. if not found then add the function as other (type=O). Only do this if we know which module we're in.
     1258     *  4b. do 3.
    10761259     */
    10771260
    1078     /* 1. */
     1261    /*
     1262     * (1) Read function declaration using analyseFnDcl2.
     1263     */
    10791264    ulRc = analyseFnDcl2(pFnDesc, papszLines, i, iRet, pszFilename, pOptions);
    10801265    if (ulRc != 1)
    10811266        return ulRc;
    10821267
    1083     /* 2. */
     1268    /*
     1269     * (2) Apply name rules (if api only?).
     1270     */
    10841271    if (pOptions->fOS2 && strncmp(pFnDesc->pszName, "OS2", 3) == 0)
    10851272        pFnDesc->pszName += 3;
     
    10911278        pFnDesc->pszName += 3;
    10921279
    1093     /* 3. */
    1094     if (!dbFindFunction(pFnDesc->pszName, &FnFindBuf, pOptions->lDllRefcode))
     1280    /*
     1281     * (3) Do a database lookup on the name.
     1282     */
     1283    if (!dbFindFunction(pFnDesc->pszName, &FnFindBuf, pOptions->lModRefcode))
    10951284    {
    10961285        fprintf(phSignal, "%s, %s: error occured while reading from database, %s\n",
     
    11021291    if (FnFindBuf.cFns != 0)
    11031292    {
    1104         if (pOptions->lDllRefcode < 0)
     1293        if (pOptions->lModRefcode < 0)
    11051294        {
    11061295            if (FnFindBuf.cFns > 1)
    11071296            {
    1108                 fprintf(phSignal, "%s: unknown dll and more than two occurences of this function!\n", pszFilename);
     1297                fprintf(phSignal, "%s: unknown module and more than two occurences of this function!\n", pszFilename);
    11091298                return 0x00010000;
    11101299            }
    1111             pOptions->lDllRefcode = FnFindBuf.alDllRefCode[0];
    1112             fprintf(phLog, "DllRef = %d\n", pOptions->lDllRefcode);
     1300            pOptions->lModRefcode = FnFindBuf.alModRefCode[0];
     1301            logprintf((phLog, "ModRef = %d\n", pOptions->lModRefcode));
    11131302        }
    11141303
     
    11171306
    11181307        if (pFnDesc->cRefCodes == 0)
    1119             fprintf(phLog, "%s was not an API in this dll(%d)!\n", pFnDesc->pszName, pOptions->lDllRefcode);
     1308            logprintf((phLog, "%s was not an API in this module(%d)!\n", pFnDesc->pszName, pOptions->lModRefcode));
    11201309    }
    11211310    else
    1122         fprintf(phLog, "%s was not an API\n", pFnDesc->pszName);
     1311        logprintf((phLog, "%s was not an API\n", pFnDesc->pszName));
     1312
     1313    /*
     1314     * (4) If not found then add the function as other (type=O).
     1315     *     Only do this if we know which module we're in.
     1316     */
     1317    if (FnFindBuf.cFns == 0 || pFnDesc->cRefCodes == 0 && pOptions->lModRefcode >= 0)
     1318    {
     1319        if (!dbInsertUpdateFunction(pOptions->lModRefcode,
     1320                                    pFnDesc->pszName, pFnDesc->pszName,
     1321                                    -1, TRUE, FUNCTION_OTHER))
     1322        {
     1323            fprintf(phSignal, "%s, %s: error occured inserting new function, %s\n",
     1324                    pszFilename, pFnDesc->pszName, dbGetLastErrorDesc());
     1325            return 0x00010000;
     1326        }
     1327
     1328        if (!dbFindFunction(pFnDesc->pszName, &FnFindBuf, pOptions->lModRefcode))
     1329        {
     1330            fprintf(phSignal, "%s, %s: error occured while reading from database, %s\n",
     1331                    pszFilename, pFnDesc->pszName, dbGetLastErrorDesc());
     1332            return 0x00010000;
     1333        }
     1334
     1335        for (lFn = 0; lFn < FnFindBuf.cFns; lFn++)
     1336            pFnDesc->alRefCode[pFnDesc->cRefCodes++] = FnFindBuf.alRefCode[lFn];
     1337
     1338        if (pFnDesc->cRefCodes == 0)
     1339        {
     1340            fprintf(phSignal, "%s, %s: Function was not found even though it was just added.\n",
     1341                    pszFilename, pFnDesc->pszName);
     1342            return 0x00010000;
     1343        }
     1344    }
    11231345
    11241346    ulRc = pFnDesc->cRefCodes;
     
    11431365{
    11441366    /** @sketch
    1145      * 1. find the '('
    1146      * 2. find the word ahead of the '(', this is the function name.
    1147      * 2a. class test.
    1148      * 3. find the closing ')'
    1149      * 4. copy the parameters, which is between the two '()'
    1150      * 5. format the parameters
     1367     * 1. Find the '('
     1368     * 2. Find the word ahead of the '(', this is the function name.
     1369     * 2a. Class test.
     1370     * 3. Find the closing ')'
     1371     * 4. Copy the parameters, which is between the two '()'
     1372     * 5. Format the parameters
     1373     * 6. Return type, function name and arguments.
     1374     *    Check for the ODINFUNCTION macro.
    11511375     */
    11521376
     
    11711395    }
    11721396
    1173     /* 2. */
     1397    /*
     1398     * (2) find the word ahead of the '(', this is the function name.
     1399     */
    11741400    iFn = iP1;
    11751401    if (papszLines[iFn] != pszP1)
     
    11991425    pszFn = findStartOfWord(pszFn, papszLines[iFn]);
    12001426
    1201     /* 2a. */
     1427    /*
     1428     * (2a) class test.
     1429     */
    12021430    /* operators are not supported (BOOL kTime::operator > (const kTime &time) const) */
    12031431    if (pszFn > papszLines[iFn])
     
    12251453        pszClass = pszClassEnd = NULL;
    12261454
    1227     /* 3. */
     1455    /*
     1456     * (3) find the closing ')'
     1457     */
    12281458    c = 1;
    12291459    iP2 = iP1;
     
    12431473    iRet = iP2 + 1; //assumes: only one function on a single line!
    12441474
    1245     /* 4. */
     1475    /*
     1476     * (4) Copy the parameters, which is between the two '()'
     1477     */
    12461478    psz = pFnDesc->szFnDclBuffer;
    12471479    copy(pFnDesc->szFnDclBuffer, pszP1, iP1, pszP2, iP2, papszLines);
    12481480    pszEnd = psz + strlen(psz) + 1;
    12491481
    1250     /* 5.*/
     1482    /*
     1483     * (5) Format the parameters.
     1484     */
    12511485    cArgs = 0;
    12521486    if (stricmp(psz, "(void)") != 0 && strcmp(psz, "()") != 0 && strcmp(psz, "( )"))
     
    12751509    }
    12761510
    1277     /* 6. */
     1511    /*
     1512     * (6) Return type, function name and arguments.
     1513     *     Check for the ODINFUNCTION macro.
     1514     */
    12781515    if (strnicmp(pszFn, "ODINFUNCTION", 12) == 0 || strnicmp(pszFn, "ODINPROCEDURE", 13) == 0)
    12791516    {
     
    13251562            /* FIXME LATER! Some constructors calling baseclass constructors "breaks" this rule. Win32MDIChildWindow in /src/user32/win32wmdichild.cpp for example. */
    13261563            fprintf(phSignal,"Fatal error? return statement is too larget. len=%d\n", strlen(pszEnd));
    1327             fprintf(phLog,   "Fatal error? return statement is too larget. len=%d\n", strlen(pszEnd));
     1564            logprintf((phLog,   "Fatal error? return statement is too larget. len=%d\n", strlen(pszEnd)));
    13281565            if (strlen(pszEnd) > 512)
    13291566                fprintf(stderr,  "Fatal error? return statement is too larget. len=%d\n", strlen(pszEnd));
     1567            #ifdef DEBUGLOG
    13301568            fflush(phLog);
     1569            #endif
    13311570            fflush(phSignal);
    13321571            fflush(stderr);
     
    13391578        /* !BugFix! some function occur more than once, usually as inline functions */
    13401579        if (pFnDesc->pszReturnType != NULL
    1341             && strstr(pFnDesc->pszReturnType, "inline ") != NULL)
    1342         {
    1343             fprintf(phLog, "Not an API. Inlined functions can't be exported!\n");
     1580            && (pFnDesc->fchType == FUNCTION_ODIN32_API || pFnDesc->fchType == FUNCTION_INTERNAL_ODIN32_API)
     1581            && stristr(pFnDesc->pszReturnType, "inline ") != NULL)
     1582        {
     1583            logprintf((phLog, "Not an API. Inlined functions can't be exported!\n"));
    13441584            return 0;
    13451585        }
     
    13531593            )
    13541594        {   /* cdecl function is prefixed with an '_' */
    1355             strcpy(pszEnd, "_");
     1595            strcpy(pszEnd, "_"); /* BUGBUG */
    13561596        }
    13571597        if (pszClass != NULL)
     
    13651605        *pszEnd = '\0';
    13661606
     1607        /* class name and type */
     1608        if (pszClass != NULL)
     1609        {
     1610            pFnDesc->pszClass = pszEnd;
     1611            strncat(pszEnd,pszClass, pszClassEnd - pszClass + 1);
     1612            if (!pFnDesc->pszReturnType || !*pFnDesc->pszReturnType)
     1613                pFnDesc->fchType =  *pszFn != '~' ? FUNCTION_CONSTRUCTOR : FUNCTION_DESTRUCTOR;
     1614            else
     1615                pFnDesc->fchType = FUNCTION_METHOD; /* BUGBUG operator. */
     1616            pszEnd = strlen(pszEnd) + pszEnd + 1;
     1617            *pszEnd = '\0';
     1618        }
    13671619
    13681620        /* arguments */
     
    14071659                    else
    14081660                    {   /* arg yet another special case! 'fn(int argc, char *argv[])' */
    1409                         char *pszP2;
     1661                        char *pszP2 = NULL;
    14101662                        cch = strlen(apszArgs[j]);
    14111663                        psz = &apszArgs[j][cch-2];
     
    14371689                                memset(psz, ' ', pszP2 - psz);
    14381690                            else
    1439                                 fprintf(phLog, "assert: line %d\n", __LINE__);
     1691                                logprintf((phLog, "assert: line %d\n", __LINE__));
    14401692                        }
    14411693                        pFnDesc->apszParamType[j] = trim(apszArgs[j]);
     
    15841836        /* 2c.*/
    15851837        if (iName <= iEnd && strstr(papszLines[iName], pFnDesc->pszName) == NULL)
    1586             fprintf(phLog, "Warning: a matching function name is not found in the name Field\n");
     1838            logprintf((phLog, "Warning: a matching function name is not found in the name Field\n"));
    15871839    }
    15881840
     
    18152067}
    18162068
     2069
     2070/**
     2071 * Writes debug log data on a function.
     2072 * @param   pFnDesc     Pointer to function description block.
     2073 */
     2074void logFunction(PFNDESC pFnDesc)
     2075{
     2076    #ifdef DEBUGLOG
     2077    int j;
     2078
     2079    fprintf(phLog, "Name:      '%s'  (refcodes=", pFnDesc->pszName);
     2080    for (j = 0; j < pFnDesc->cRefCodes; j++)
     2081        fprintf(phLog, j > 0 ? ", %ld" : "%ld", pFnDesc->alRefCode[j]);
     2082    fprintf(phLog, ")\n");
     2083    fprintf(phLog, "  Returns: '%s'\n", pFnDesc->pszReturnType != NULL ? pFnDesc->pszReturnType : "<missing>");
     2084    fprintf(phLog, "  cParams: %2d\n", pFnDesc->cParams);
     2085    for (j = 0; j < pFnDesc->cParams; j++)
     2086        fprintf(phLog, "  Param %2d: type '%s' %*s name '%s' description: %s\n", j, pFnDesc->apszParamType[j],
     2087                max((int)(15 - strlen(pFnDesc->apszParamType[j])), 0), "", pFnDesc->apszParamName[j],
     2088                pFnDesc->apszParamDesc[j] != NULL ?  pFnDesc->apszParamDesc[j] : "(null)");
     2089    fprintf(phLog, "  Status:   %ld - '%s'\n", pFnDesc->lStatus, pFnDesc->pszStatus != NULL ? pFnDesc->pszStatus : "<missing>");
     2090    fprintf(phLog, "  cAuthors: %2d\n", pFnDesc->cAuthors);
     2091    for (j = 0; j < pFnDesc->cAuthors; j++)
     2092        fprintf(phLog, "  Author %d: '%s'  (refcode=%ld)\n", j, pFnDesc->apszAuthor[j], pFnDesc->alAuthorRefCode[j]);
     2093
     2094    fprintf(phLog, "  Description: %s\n", pFnDesc->pszDescription != NULL ? pFnDesc->pszDescription : "(null)");
     2095    fprintf(phLog, "  Remark:      %s\n", pFnDesc->pszRemark != NULL ? pFnDesc->pszRemark : "(null)");
     2096    fprintf(phLog, "  Return Desc: %s\n", pFnDesc->pszReturnDesc != NULL ? pFnDesc->pszReturnDesc : "(null)");
     2097    fprintf(phLog, "  Sketch:      %s\n", pFnDesc->pszSketch != NULL ? pFnDesc->pszSketch : "(null)");
     2098    fprintf(phLog, "  Equiv:       %s\n", pFnDesc->pszEquiv != NULL ? pFnDesc->pszEquiv : "(null)");
     2099    fprintf(phLog, "  Time:        %s\n", pFnDesc->pszTime != NULL ? pFnDesc->pszTime : "(null)");
     2100    fprintf(phLog, "------------\n");
     2101    #else
     2102    pFnDesc = pFnDesc;
     2103    #endif
     2104}
     2105
     2106
     2107/**
     2108 * Resolves the source filename of an .obj file.
     2109 * @returns Pointer to static filename buffer.
     2110 * @param   pszFileObj  Name of object file.
     2111 * @param   papszDirs   Array of directories to search. NULL terminated.
     2112 * @remark  The string returned is in _static_ memory.
     2113 */
     2114char *ResolvSourceFile(char *pszFileObj, char **papszDirs)
     2115{
     2116    static char     szFile[CCHMAXPATH];
     2117    static char *   aszSuffixes[] = { ".cpp", ".c", ".orc", NULL };
     2118    char *  aszDirs[] = { ".;", NULL };
     2119    char *  pszDir;
     2120    int     i;
     2121    char    szFileTmp[CCHMAXPATH];
     2122
     2123    /*
     2124     * Extract file name.
     2125     */
     2126    fileNameNoExt(pszFileObj, szFileTmp);
     2127
     2128
     2129    /*
     2130     * Loop dirs.
     2131     */
     2132    for (i = 0; papszDirs[i]; i++)
     2133    {
     2134        int j;
     2135
     2136        for (j = 0; aszSuffixes[j]; j++)
     2137        {
     2138            APIRET       rc;
     2139            FILESTATUS3  fs;
     2140
     2141            strcat(strcat(strcat(strcpy(szFile, papszDirs[i]), "\\"), szFileTmp), aszSuffixes[j]);
     2142            rc = DosQueryPathInfo(szFile, FIL_STANDARD, &fs , sizeof(fs));
     2143            if (rc == NO_ERROR && (fs.attrFile & FILE_DIRECTORY) != FILE_DIRECTORY)
     2144            {
     2145                logprintf((phLog, "ResolveSourceFile(%s,..) -> %s\n", pszFileObj, szFile));
     2146                return szFile;
     2147            }
     2148        }
     2149    }
     2150
     2151    logprintf((phLog, "ResolveSourceFile(%s,..) -> NULL\n", pszFileObj));
     2152    return NULL;
     2153}
    18172154
    18182155
     
    21612498                                if (pszB != NULL && *pszB == '{')
    21622499                                {
    2163                                     fprintf(phLog, "Function found: %.*s\n", cchFnName, pszFnName);
     2500                                    logprintf((phLog, "Function found: %.*s\n", cchFnName, pszFnName));
    21642501                                    return TRUE;
    21652502                                }
     
    22242561                        if (pszB != NULL && *pszB == '{')
    22252562                        {
    2226                             fprintf(phLog, "Possible API: %.*s\n", cchFnName, pszOS2);
     2563                            logprintf((phLog, "Possible API: %.*s\n", cchFnName, pszOS2));
    22272564                            return TRUE;
    22282565                        }
     
    22662603
    22672604
     2605/**
     2606 * Checks if there is a class declaration starting at the current line.
     2607 * @returns   TRUE if design note found, else FALSE.
     2608 * @param     papszLines   Array of lines in the file.
     2609 * @param     i            Index into papszLines.
     2610 * @param     pOptions     Pointer to options.
     2611 */
     2612BOOL isClass(char **papszLines, int i, POPTIONS pOptions)
     2613{
     2614    char *psz = papszLines[i];
     2615
     2616    if (psz == NULL)
     2617        return FALSE;
     2618
     2619    // look for class
     2620    while (*psz == ' ')
     2621        psz++;
     2622
     2623    pOptions = pOptions;
     2624    return !strncmp(psz, "class", 5)
     2625           && (psz[5] == '\t' || psz[5] == ' ' || psz[5] == '\n' || psz[5] == '\r' || psz[5] == '\0');
     2626}
     2627
    22682628
    22692629
     
    22782638    {
    22792639        case 0:
    2280             fprintf(phLog, "%s", pszValue);
     2640            logprintf((phLog, "%s", pszValue));
    22812641            break;
    22822642        case 1:
    2283             fprintf(phLog, "(%s)", pszValue);
     2643            logprintf((phLog, "(%s)", pszValue));
    22842644            break;
    22852645        case 2: /* updated */
    2286             fprintf(phLog, " %s=%s", pszFieldName, pszValue);
     2646            logprintf((phLog, " %s=%s", pszFieldName, pszValue));
    22872647            break;
    22882648        case 3: /* aliasfn */
    2289             fprintf(phLog, " %s=%s", pszFieldName, pszValue);
     2649            logprintf((phLog, " %s=%s", pszFieldName, pszValue));
    22902650            break;
    22912651        case 4:
    22922652            if (pszValue != NULL)
    2293                 fprintf(phLog, " --> %s.", pszValue);
     2653                logprintf((phLog, " --> %s.", pszValue));
    22942654            break;
    22952655        case 5:
    22962656            if (pszValue != NULL)
    2297                 fprintf(phLog, "%s", pszValue);
     2657                logprintf((phLog, "%s", pszValue));
    22982658            break;
    22992659        case 6:
    23002660            if (pszValue != NULL)
    2301                 fprintf(phLog, "(%s)", pszValue);
     2661                logprintf((phLog, "(%s)", pszValue));
    23022662            break;
    23032663
    23042664        default:
    23052665            i = 0;
    2306             fprintf(phLog, "\n");
     2666            logprintf((phLog, "\n"));
    23072667    }
    23082668
     
    23102670    {
    23112671        i = 0;
    2312         fprintf(phLog, "\n");
     2672        logprintf((phLog, "\n"));
    23132673    }
    23142674
     
    24412801        psz++;
    24422802    }
    2443     fprintf(phLog, "%d lines\n", cLines);
     2803    logprintf((phLog, "%d lines\n", cLines));
    24442804
    24452805    papszLines = (char**)calloc(cLines + 1, sizeof(char *));
     
    29943354
    29953355
    2996 
    2997 
     3356/**
     3357 * Creates a memory buffer for a text file.
     3358 * @returns   Pointer to file memoryblock. NULL on error.
     3359 * @param     pszFilename  Pointer to filename string.
     3360 * @remark    This function is the one using most of the execution
     3361 *            time (DosRead + DosOpen) - about 70% of the execution time!
     3362 */
     3363void *textbufferCreate(const char *pszFilename)
     3364{
     3365    void *pvFile = NULL;
     3366    FILE *phFile;
     3367
     3368    phFile = fopen(pszFilename, "rb");
     3369    if (phFile != NULL)
     3370    {
     3371        signed long cbFile = fsize(phFile);
     3372        if (cbFile >= 0)
     3373        {
     3374            pvFile = malloc(cbFile + 1);
     3375            if (pvFile != NULL)
     3376            {
     3377                memset(pvFile, 0, cbFile + 1);
     3378                if (cbFile > 0 && fread(pvFile, 1, cbFile, phFile) == 0)
     3379                {   /* failed! */
     3380                    free(pvFile);
     3381                    pvFile = NULL;
     3382                }
     3383            }
     3384            else
     3385                fprintf(stderr, "warning/error: failed to open file %s\n", pszFilename);
     3386        }
     3387        fclose(phFile);
     3388    }
     3389    return pvFile;
     3390}
     3391
     3392
     3393/**
     3394 * Destroys a text textbuffer.
     3395 * @param     pvBuffer   Buffer handle.
     3396 */
     3397void textbufferDestroy(void *pvBuffer)
     3398{
     3399    free(pvBuffer);
     3400}
     3401
     3402
     3403/**
     3404 * Gets the next line from an textbuffer.
     3405 * @returns   Pointer to the next line.
     3406 * @param     pvBuffer  Buffer handle.
     3407 * @param     psz       Pointer to current line.
     3408 *                      NULL is passed in to get the first line.
     3409 */
     3410char *textbufferNextLine(void *pvBuffer, register char *psz)
     3411{
     3412    register char ch;
     3413
     3414    /* if first line psz is NULL. */
     3415    if (psz == NULL)
     3416        return (char*)pvBuffer;
     3417
     3418    /* skip till end of file or end of line. */
     3419    ch = *psz;
     3420    while (ch != '\0' && ch != '\n' && ch != '\r')
     3421        ch = *++psz;
     3422
     3423    /* skip line end */
     3424    if (ch == '\r')
     3425        ch = *++psz;
     3426    if (ch == '\n')
     3427        psz++;
     3428
     3429    return psz;
     3430}
     3431
     3432
     3433/**
     3434 * Gets the next line from an textbuffer.
     3435 * (fgets for textbuffer)
     3436 * @returns   Pointer to pszOutBuffer. NULL when end of file.
     3437 * @param     pvBuffer  Buffer handle.
     3438 * @param     ppv       Pointer to a buffer index pointer. (holds the current buffer index)
     3439 *                      Pointer to a null pointer is passed in to get the first line.
     3440 * @param     pszLineBuffer  Output line buffer. (!= NULL)
     3441 * @param     cchLineBuffer  Size of the output line buffer. (> 0)
     3442 * @remark    '\n' and '\r' are removed!
     3443 */
     3444char *textbufferGetNextLine(void *pvBuffer, void **ppv, char *pszLineBuffer, int cchLineBuffer)
     3445{
     3446    char *          pszLine = pszLineBuffer;
     3447    char *          psz = *(char**)(void*)ppv;
     3448    register char   ch;
     3449
     3450    /* first line? */
     3451    if (psz == NULL)
     3452        psz = (char*)pvBuffer;
     3453
     3454    /* Copy to end of the line or end of the linebuffer. */
     3455    ch = *psz;
     3456    cchLineBuffer--; /* reserve space for '\0' */
     3457    while (cchLineBuffer > 0 && ch != '\0' && ch != '\n' && ch != '\r')
     3458    {
     3459        *pszLine++ = ch;
     3460        ch = *++psz;
     3461    }
     3462    *pszLine = '\0';
     3463
     3464    /* skip line end */
     3465    if (ch == '\r')
     3466        ch = *++psz;
     3467    if (ch == '\n')
     3468        psz++;
     3469
     3470    /* check if position has changed - if unchanged it's the end of file! */
     3471    if (*ppv == (void*)psz)
     3472        pszLineBuffer = NULL;
     3473
     3474    /* store current position */
     3475    *ppv = (void*)psz;
     3476
     3477    return pszLineBuffer;
     3478}
     3479
     3480
     3481/**
     3482 * Find the size of a file.
     3483 * @returns   Size of file. -1 on error.
     3484 * @param     phFile  File handle.
     3485 */
     3486signed long fsize(FILE *phFile)
     3487{
     3488    int ipos;
     3489    signed long cb;
     3490
     3491    if ((ipos = ftell(phFile)) < 0
     3492        ||
     3493        fseek(phFile, 0, SEEK_END) != 0
     3494        ||
     3495        (cb = ftell(phFile)) < 0
     3496        ||
     3497        fseek(phFile, ipos, SEEK_SET) != 0
     3498        )
     3499        cb = -1;
     3500    return cb;
     3501}
     3502
     3503
     3504/**
     3505 * Copies the name part with out extention into pszBuffer and returns
     3506 * a pointer to the buffer.
     3507 * If no name is found "" is returned.
     3508 * @returns   Pointer to pszBuffer with path.
     3509 * @param     pszFilename  Pointer to readonly filename.
     3510 * @param     pszBuffer    Pointer to output Buffer.
     3511 * @status    completely implemented.
     3512 * @author    knut st. osmundsen
     3513 */
     3514char *fileNameNoExt(const char *pszFilename, char *pszBuffer)
     3515{
     3516    char *psz = strrchr(pszFilename, '\\');
     3517    if (psz == NULL)
     3518        psz = strrchr(pszFilename, '/');
     3519
     3520    strcpy(pszBuffer, psz == NULL ? pszFilename : psz + 1);
     3521
     3522    psz = strrchr(pszBuffer, '.');
     3523    if (psz > pszBuffer) /* an extetion on it's own (.depend) is a filename not an extetion! */
     3524        *psz = '\0';
     3525
     3526    return pszBuffer;
     3527}
     3528
Note: See TracChangeset for help on using the changeset viewer.