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