Changeset 6677 for trunk/tools/database/StateUpd.cpp
- Timestamp:
- Sep 7, 2001, 12:26:42 PM (24 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/tools/database/StateUpd.cpp
r6665 r6677 1 /* $Id: StateUpd.cpp,v 1.3 7 2001-09-06 03:17:37bird Exp $1 /* $Id: StateUpd.cpp,v 1.38 2001-09-07 10:24:06 bird Exp $ 2 2 * 3 3 * StateUpd - Scans source files for API functions and imports data on them. … … 8 8 9 9 /******************************************************************************* 10 * Header Files*10 * Defined Constants And Macros * 11 11 *******************************************************************************/ 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 12 19 #define INCL_DOSFILEMGR 13 20 #define INCL_DOSERRORS 14 21 #define INCL_DOSMISC 15 22 #define INCL_DOSPROCESS 23 24 25 /******************************************************************************* 26 * Header Files * 27 *******************************************************************************/ 16 28 #include <os2.h> 17 29 #include <malloc.h> … … 24 36 #include "db.h" 25 37 26 27 28 38 /******************************************************************************* 29 39 * Global Variables * 30 40 *******************************************************************************/ 41 #ifdef DEBUGLOG 31 42 static FILE *phLog = NULL; 43 #endif 32 44 static FILE *phSignal = NULL; 33 45 … … 46 58 static void closeLogs(void); 47 59 static unsigned long processDir(const char *pszDirOrFile, POPTIONS pOptions); 48 static unsigned long processFile(const char *pszFilename, POPTIONS pOptions );49 static unsigned long process ModuleHeader(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);60 static unsigned long processFile(const char *pszFilename, POPTIONS pOptions, BOOL fHeader); 61 static unsigned long processFileHeader(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions); 50 62 static unsigned long processDesignNote(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions); 51 static unsigned long process API(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions);63 static unsigned long processFunction(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions); 52 64 static unsigned long analyseFnHdr(PFNDESC pFnDesc, char **papszLines, int i, const char *pszFilename, POPTIONS pOptions); 53 65 static unsigned long analyseFnDcl(PFNDESC pFnDesc, char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions); 54 66 static unsigned long analyseFnDcl2(PFNDESC pFnDesc, char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions); 67 static void logFunction(PFNDESC pFnDesc); 68 static char *ResolvSourceFile(char *pszFileObj, char **papszDirs); 55 69 static char *SDSCopyTextUntilNextTag(char *pszTarget, BOOL fHTML, int iStart, int iEnd, char **papszLines, const char *pszStart = NULL); 56 70 static char *CommonCopyTextUntilNextTag(char *pszTarget, BOOL fHTML, int iStart, int iEnd, char **papszLines, const char *pszStart = NULL); 57 71 static BOOL isFunction(char **papszLines, int i, POPTIONS pOptions); 58 72 static BOOL isDesignNote(char **papszLines, int i, POPTIONS pOptions); 73 static BOOL isClass(char **papszLines, int i, POPTIONS pOptions); 59 74 static long _System dbNotUpdatedCallBack(const char *pszValue, const char *pszFieldName, void *pvUser); 60 75 static char *skipInsignificantChars(char **papszLines, int &i, char *psz); … … 74 89 static char *skipBackwards(const char *pszStopAt, const char *pszFrom, int &iLine, char **papszLines); 75 90 static int findStrLine(const char *psz, int iStart, int iEnd, char **papszLines); 91 static void *textbufferCreate(const char *pszFilename); 92 static char *textbufferGetNextLine(void *pvBuffer, void **ppv, char *pszLineBuffer, int cchLineBuffer); 93 static char *textbufferNextLine(void *pvBuffer, register char *psz); 94 static void textbufferDestroy(void *pvBuffer); 95 static signed long fsize(FILE *phFile); 96 static char *fileNameNoExt(const char *pszFilename, char *pszBuffer); 76 97 77 98 … … 87 108 BOOL fFatal = FALSE; 88 109 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 }; 91 127 unsigned long ulRc2; 92 128 char *pszErrorDesc = NULL; … … 101 137 /*DosSetPriority(PRTYS_PROCESSTREE, PRTYC_REGULAR, 1, 0);*/ 102 138 103 /* get dllname from directory */139 /* get module name from directory */ 104 140 ul1 = ul2 = 0; 105 141 DosQueryCurrentDisk(&ul1, &ul2); 106 ul2 = sizeof(sz DLLName);107 DosQueryCurrentDir(ul1, &sz DLLName[0], &ul2);142 ul2 = sizeof(szModName); 143 DosQueryCurrentDir(ul1, &szModName[0], &ul2); 108 144 if (ul2 != 0) 109 145 { 110 if (sz DLLName[ul2-1] == '\\' || szDLLName[ul2-1] == '/')111 sz DLLName[--ul2] = '\0';146 if (szModName[ul2-1] == '\\' || szModName[ul2-1] == '/') 147 szModName[--ul2] = '\0'; 112 148 ul1 = ul2; 113 while (ul1 != 0 && sz DLLName[ul1-1] != '\\' && szDLLName[ul1-1] != '/')149 while (ul1 != 0 && szModName[ul1-1] != '\\' && szModName[ul1-1] != '/') 114 150 ul1--; 115 151 if (ul1 != 0) 116 options.psz DLLName = &szDLLName[ul1];152 options.pszModName = &szModName[ul1]; 117 153 } 118 154 else 119 sz DLLName[0] = '\0';155 szModName[0] = '\0'; 120 156 121 157 … … 127 163 * -io Integrity check only. 128 164 * -s Scan subdirectories. 129 * -Old <[+]|-> Old API Style.130 165 * -OS2<[+]|-> Removes 'OS2'-prefix from function name. 131 166 * -COMCTL32<[+]|-> Removes 'COMCTL32'-prefix from function name. 132 167 * -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. 134 170 * -d:<dbname> Database name 135 171 * -p:<passwd> Password … … 147 183 case 'D': 148 184 if (strnicmp(&argv[argi][1], "dll:", 4) == 0 ) 149 options.psz DLLName = &argv[argi][5];185 options.pszModName = &argv[argi][5]; 150 186 else 151 187 { … … 157 193 break; 158 194 195 case '-': 159 196 case 'h': 160 197 case 'H': … … 192 229 } 193 230 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 194 243 195 244 case 'o': … … 217 266 case 'S': 218 267 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"); 220 269 break; 221 270 … … 228 277 break; 229 278 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 230 299 default: 231 300 fprintf(stderr, "incorrect parameter. (argi=%d, argv[argi]=%s)\n", argi, argv[argi]); … … 234 303 } 235 304 } 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 } 236 363 else 237 364 break; /* files has started */ … … 266 393 } 267 394 395 268 396 if (!options.fIntegrityOnly) 269 397 { 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) 274 406 { 275 407 /* processing */ … … 277 409 ulRc = processDir(".", &options); 278 410 else 279 while (arg v[argi] != NULL)411 while (argi < argc) 280 412 { 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); 282 434 argi++; 283 435 } … … 309 461 } 310 462 else 311 { /* failed to find dll- concidered nearly fatal. */312 fprintf(phSignal, "-,-: failed to find dll(%s)!\n\t%s\n",313 options.psz DLLName ? 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>", 314 466 dbGetLastErrorDesc()); 315 467 ulRc++; … … 320 472 if (!options.fIntegrityOnly) 321 473 { 322 cUpdated = dbGetNumberOfUpdatedFunction(options.l DllRefcode);323 cAll = dbCountFunctionIn Dll(options.lDllRefcode, FALSE);324 cNotAliased = dbCountFunctionIn Dll(options.lDllRefcode, TRUE);474 cUpdated = dbGetNumberOfUpdatedFunction(options.lModRefcode); 475 cAll = dbCountFunctionInModule(options.lModRefcode, FALSE); 476 cNotAliased = dbCountFunctionInModule(options.lModRefcode, TRUE); 325 477 if (cNotAliased > cUpdated) 326 478 { … … 329 481 ulRc += 0x00010000; 330 482 } 331 fprintf(phLog, "-------------------------------------------------\n");332 fprintf(phLog, "-------- Functions which was not updated --------\n");333 dbGetNotUpdatedFunction(options.l DllRefcode, 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))); 340 492 341 493 /* close the logs */ … … 348 500 if (!options.fIntegrityOnly) 349 501 { 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)); 354 506 if ((int)(ulRc >> 16) > 0) 355 507 fprintf(stderr, "Check signal file 'Signals.Log'.\n"); … … 376 528 " -io Integrity check only. default: disabled\n" 377 529 " -s Scan subdirectories. default: disabled\n" 378 " -Old Use old API style. default: disabled\n"379 530 " -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" 381 533 " -h:<hostname> Database server hostname. default: localhost\n" 382 534 " -u:<username> Username on the server. default: root\n" … … 402 554 static void openLogs(void) 403 555 { 556 #ifdef DEBUGLOG 404 557 if (phLog == NULL) 405 558 { … … 411 564 } 412 565 } 566 #endif 413 567 414 568 if (phSignal == NULL) … … 429 583 static void closeLogs(void) 430 584 { 585 #ifdef DEBUGLOG 431 586 if (phLog != stderr && phLog != NULL) 432 587 fclose(phLog); 588 #endif 433 589 if (phSignal != stdout && phSignal != NULL) 434 590 { … … 473 629 rc = DosQueryPathInfo(pszDirOrFile, FIL_STANDARD, &fs , sizeof(fs)); 474 630 fFile = rc == NO_ERROR && (fs.attrFile & FILE_DIRECTORY) != FILE_DIRECTORY; 631 if (!fFile) 632 fFile = strpbrk(pszDirOrFile, "*?") != NULL; 475 633 476 634 /* 0. */ … … 510 668 char *psz = strrchr(&ffb.achName[0], '.'); 511 669 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); 513 673 514 674 /* next */ … … 551 711 /** 552 712 * 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. 557 718 * @sketch 1. read file into memory. 558 719 * 2. create line array. 559 720 * (3. simple preprocessing - TODO) 560 * 4. process module header.721 * 4. process file header. 561 722 * 5. scan thru the line array, looking for APIs and designnotes. 562 723 * 5b. when API is found, process it. 563 724 * 5c. when designnote found, process it. 564 725 */ 565 static unsigned long processFile(const char *pszFilename, POPTIONS pOptions )726 static unsigned long processFile(const char *pszFilename, POPTIONS pOptions, BOOL fHeader) 566 727 { 567 728 unsigned long cSignals = 0; … … 569 730 char *pszFile; 570 731 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 */ 573 737 pszFile = readFileIntoMemory(pszFilename); 574 738 if (pszFile != NULL) … … 576 740 char **papszLines; 577 741 578 /* 2.*/ 742 /* 743 * (2) Create line array. 744 */ 579 745 papszLines = createLineArray(pszFile); 580 746 if (papszLines != NULL) … … 583 749 int i = 0; 584 750 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); 589 760 cSignals += ulRc >> 16; 590 761 if (ulRc & 0x0000ffff) 591 762 { 592 /* 4b.593 * Remove Design notes.763 /* 764 * (4b) Remove Design notes. 594 765 */ 595 pOptions->lSeqFile = 0;596 766 if (!dbRemoveDesignNotes(pOptions->lFileRefcode)) 597 767 { … … 602 772 603 773 604 /* 5.*/ 774 /* 775 * (5) The scan loop. 776 */ 605 777 while (papszLines[i] != NULL) 606 778 { 779 /* 780 * (5b) Function. 781 */ 607 782 if (isFunction(papszLines, i, pOptions)) 608 783 { 609 ulRc = process API(papszLines, i, i, pszFilename, pOptions);784 ulRc = processFunction(papszLines, i, i, pszFilename, pOptions); 610 785 cAPIs += 0x0000ffff & ulRc; 611 786 cSignals += ulRc >> 16; 612 787 } 613 else 788 /* 789 * (5c) Design note. 790 */ 791 else if (isDesignNote(papszLines, i, pOptions)) 614 792 { 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])); 620 803 i++; 621 804 } 622 } 623 } 624 805 #endif 806 /* 807 * Nothing. 808 */ 809 else 810 i++; 811 } /* while - scan loop */ 812 } 813 814 /* 815 * Cleanup. 816 */ 625 817 free(papszLines); 626 818 } … … 637 829 cSignals++; 638 830 } 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; 641 834 642 835 return (unsigned long)((cSignals << 16) | cAPIs); … … 645 838 646 839 /** 647 * Processes an module header and other file information.840 * Processes an file header and other file information. 648 841 * @returns high word = number of signals. 649 842 * low word = Success indicator (TRUE / FALSE). … … 655 848 * @sketch Extract module information if any.... 656 849 */ 657 static unsigned long process ModuleHeader(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;850 static 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; 662 855 const char * pszDBFilename; 663 856 char * pszLastDateTime = NULL; … … 783 976 * Insert or update the database. 784 977 */ 785 if (dbInsertUpdateFile((unsigned short)pOptions->l DllRefcode, pszDBFilename,978 if (dbInsertUpdateFile((unsigned short)pOptions->lModRefcode, pszDBFilename, 786 979 &szDescription[0], pszLastDateTime, lLastAuthor, pszRevision)) 787 980 { … … 789 982 * Get file refcode. 790 983 */ 791 pOptions->lFileRefcode = dbFindFile(pOptions->l DllRefcode, pszDBFilename);984 pOptions->lFileRefcode = dbFindFile(pOptions->lModRefcode, pszDBFilename); 792 985 if (pOptions->lFileRefcode < 0) 793 986 { … … 933 1126 * Add the note. 934 1127 */ 935 if (!dbAddDesignNote(pOptions->l DllRefcode, pOptions->lFileRefcode,1128 if (!dbAddDesignNote(pOptions->lModRefcode, pOptions->lFileRefcode, 936 1129 pszTitle, psz, 937 1130 lLevel, lSeqNbr, lSeqNbrNote++, i + 1, lLevel > 0, &lRefCode)) … … 970 1163 971 1164 /** 972 * Processes an APIfunction.1165 * Processes an function. 973 1166 * @returns high word = number of signals 974 1167 * low word = number of APIs processed. (1 or 0). … … 979 1172 * @param pOptions Pointer to options. 980 1173 */ 981 static unsigned long process API(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions)1174 static unsigned long processFunction(char **papszLines, int i, int &iRet, const char *pszFilename, POPTIONS pOptions) 982 1175 { 983 1176 unsigned long ulRc; … … 999 1192 */ 1000 1193 1001 /* 1.*/ 1194 /* 1195 * (1) Analyse function declaration. 1196 */ 1002 1197 ulRc = analyseFnDcl(&FnDesc, papszLines, i, iRet, pszFilename, pOptions); 1003 1198 if (0x0000ffff & ulRc) /* if low word is 0 the fatal */ 1004 1199 { 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 */ 1010 1206 ulRcTmp = analyseFnHdr(&FnDesc, papszLines, i, pszFilename, pOptions); 1011 1207 if (ulRcTmp == ~0UL) /* check for fatal error */ 1208 { 1209 free(pszErrorDesc); 1012 1210 return (0xffff0000UL & ulRc) + 0x00010000UL; 1211 } 1013 1212 ulRc += 0xffff0000UL & ulRcTmp; 1014 1213 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); 1041 1223 if (ulRcTmp != 0) 1042 1224 { … … 1064 1246 const char *pszFilename, POPTIONS pOptions) 1065 1247 { 1066 static long lPrevFnDll = -1L; /* fix for duplicate dlls */1067 1248 unsigned long ulRc; 1068 1249 FNFINDBUF FnFindBuf; … … 1070 1251 1071 1252 /* 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. 1076 1259 */ 1077 1260 1078 /* 1. */ 1261 /* 1262 * (1) Read function declaration using analyseFnDcl2. 1263 */ 1079 1264 ulRc = analyseFnDcl2(pFnDesc, papszLines, i, iRet, pszFilename, pOptions); 1080 1265 if (ulRc != 1) 1081 1266 return ulRc; 1082 1267 1083 /* 2. */ 1268 /* 1269 * (2) Apply name rules (if api only?). 1270 */ 1084 1271 if (pOptions->fOS2 && strncmp(pFnDesc->pszName, "OS2", 3) == 0) 1085 1272 pFnDesc->pszName += 3; … … 1091 1278 pFnDesc->pszName += 3; 1092 1279 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)) 1095 1284 { 1096 1285 fprintf(phSignal, "%s, %s: error occured while reading from database, %s\n", … … 1102 1291 if (FnFindBuf.cFns != 0) 1103 1292 { 1104 if (pOptions->l DllRefcode < 0)1293 if (pOptions->lModRefcode < 0) 1105 1294 { 1106 1295 if (FnFindBuf.cFns > 1) 1107 1296 { 1108 fprintf(phSignal, "%s: unknown dlland 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); 1109 1298 return 0x00010000; 1110 1299 } 1111 pOptions->l DllRefcode = 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)); 1113 1302 } 1114 1303 … … 1117 1306 1118 1307 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)); 1120 1309 } 1121 1310 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 } 1123 1345 1124 1346 ulRc = pFnDesc->cRefCodes; … … 1143 1365 { 1144 1366 /** @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. 1151 1375 */ 1152 1376 … … 1171 1395 } 1172 1396 1173 /* 2. */ 1397 /* 1398 * (2) find the word ahead of the '(', this is the function name. 1399 */ 1174 1400 iFn = iP1; 1175 1401 if (papszLines[iFn] != pszP1) … … 1199 1425 pszFn = findStartOfWord(pszFn, papszLines[iFn]); 1200 1426 1201 /* 2a. */ 1427 /* 1428 * (2a) class test. 1429 */ 1202 1430 /* operators are not supported (BOOL kTime::operator > (const kTime &time) const) */ 1203 1431 if (pszFn > papszLines[iFn]) … … 1225 1453 pszClass = pszClassEnd = NULL; 1226 1454 1227 /* 3. */ 1455 /* 1456 * (3) find the closing ')' 1457 */ 1228 1458 c = 1; 1229 1459 iP2 = iP1; … … 1243 1473 iRet = iP2 + 1; //assumes: only one function on a single line! 1244 1474 1245 /* 4. */ 1475 /* 1476 * (4) Copy the parameters, which is between the two '()' 1477 */ 1246 1478 psz = pFnDesc->szFnDclBuffer; 1247 1479 copy(pFnDesc->szFnDclBuffer, pszP1, iP1, pszP2, iP2, papszLines); 1248 1480 pszEnd = psz + strlen(psz) + 1; 1249 1481 1250 /* 5.*/ 1482 /* 1483 * (5) Format the parameters. 1484 */ 1251 1485 cArgs = 0; 1252 1486 if (stricmp(psz, "(void)") != 0 && strcmp(psz, "()") != 0 && strcmp(psz, "( )")) … … 1275 1509 } 1276 1510 1277 /* 6. */ 1511 /* 1512 * (6) Return type, function name and arguments. 1513 * Check for the ODINFUNCTION macro. 1514 */ 1278 1515 if (strnicmp(pszFn, "ODINFUNCTION", 12) == 0 || strnicmp(pszFn, "ODINPROCEDURE", 13) == 0) 1279 1516 { … … 1325 1562 /* FIXME LATER! Some constructors calling baseclass constructors "breaks" this rule. Win32MDIChildWindow in /src/user32/win32wmdichild.cpp for example. */ 1326 1563 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))); 1328 1565 if (strlen(pszEnd) > 512) 1329 1566 fprintf(stderr, "Fatal error? return statement is too larget. len=%d\n", strlen(pszEnd)); 1567 #ifdef DEBUGLOG 1330 1568 fflush(phLog); 1569 #endif 1331 1570 fflush(phSignal); 1332 1571 fflush(stderr); … … 1339 1578 /* !BugFix! some function occur more than once, usually as inline functions */ 1340 1579 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")); 1344 1584 return 0; 1345 1585 } … … 1353 1593 ) 1354 1594 { /* cdecl function is prefixed with an '_' */ 1355 strcpy(pszEnd, "_"); 1595 strcpy(pszEnd, "_"); /* BUGBUG */ 1356 1596 } 1357 1597 if (pszClass != NULL) … … 1365 1605 *pszEnd = '\0'; 1366 1606 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 } 1367 1619 1368 1620 /* arguments */ … … 1407 1659 else 1408 1660 { /* arg yet another special case! 'fn(int argc, char *argv[])' */ 1409 char *pszP2 ;1661 char *pszP2 = NULL; 1410 1662 cch = strlen(apszArgs[j]); 1411 1663 psz = &apszArgs[j][cch-2]; … … 1437 1689 memset(psz, ' ', pszP2 - psz); 1438 1690 else 1439 fprintf(phLog, "assert: line %d\n", __LINE__);1691 logprintf((phLog, "assert: line %d\n", __LINE__)); 1440 1692 } 1441 1693 pFnDesc->apszParamType[j] = trim(apszArgs[j]); … … 1584 1836 /* 2c.*/ 1585 1837 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")); 1587 1839 } 1588 1840 … … 1815 2067 } 1816 2068 2069 2070 /** 2071 * Writes debug log data on a function. 2072 * @param pFnDesc Pointer to function description block. 2073 */ 2074 void 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 */ 2114 char *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 } 1817 2154 1818 2155 … … 2161 2498 if (pszB != NULL && *pszB == '{') 2162 2499 { 2163 fprintf(phLog, "Function found: %.*s\n", cchFnName, pszFnName);2500 logprintf((phLog, "Function found: %.*s\n", cchFnName, pszFnName)); 2164 2501 return TRUE; 2165 2502 } … … 2224 2561 if (pszB != NULL && *pszB == '{') 2225 2562 { 2226 fprintf(phLog, "Possible API: %.*s\n", cchFnName, pszOS2);2563 logprintf((phLog, "Possible API: %.*s\n", cchFnName, pszOS2)); 2227 2564 return TRUE; 2228 2565 } … … 2266 2603 2267 2604 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 */ 2612 BOOL 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 2268 2628 2269 2629 … … 2278 2638 { 2279 2639 case 0: 2280 fprintf(phLog, "%s", pszValue);2640 logprintf((phLog, "%s", pszValue)); 2281 2641 break; 2282 2642 case 1: 2283 fprintf(phLog, "(%s)", pszValue);2643 logprintf((phLog, "(%s)", pszValue)); 2284 2644 break; 2285 2645 case 2: /* updated */ 2286 fprintf(phLog, " %s=%s", pszFieldName, pszValue);2646 logprintf((phLog, " %s=%s", pszFieldName, pszValue)); 2287 2647 break; 2288 2648 case 3: /* aliasfn */ 2289 fprintf(phLog, " %s=%s", pszFieldName, pszValue);2649 logprintf((phLog, " %s=%s", pszFieldName, pszValue)); 2290 2650 break; 2291 2651 case 4: 2292 2652 if (pszValue != NULL) 2293 fprintf(phLog, " --> %s.", pszValue);2653 logprintf((phLog, " --> %s.", pszValue)); 2294 2654 break; 2295 2655 case 5: 2296 2656 if (pszValue != NULL) 2297 fprintf(phLog, "%s", pszValue);2657 logprintf((phLog, "%s", pszValue)); 2298 2658 break; 2299 2659 case 6: 2300 2660 if (pszValue != NULL) 2301 fprintf(phLog, "(%s)", pszValue);2661 logprintf((phLog, "(%s)", pszValue)); 2302 2662 break; 2303 2663 2304 2664 default: 2305 2665 i = 0; 2306 fprintf(phLog, "\n");2666 logprintf((phLog, "\n")); 2307 2667 } 2308 2668 … … 2310 2670 { 2311 2671 i = 0; 2312 fprintf(phLog, "\n");2672 logprintf((phLog, "\n")); 2313 2673 } 2314 2674 … … 2441 2801 psz++; 2442 2802 } 2443 fprintf(phLog, "%d lines\n", cLines);2803 logprintf((phLog, "%d lines\n", cLines)); 2444 2804 2445 2805 papszLines = (char**)calloc(cLines + 1, sizeof(char *)); … … 2994 3354 2995 3355 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 */ 3363 void *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 */ 3397 void 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 */ 3410 char *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 */ 3444 char *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 */ 3486 signed 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 */ 3514 char *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.