Changeset 907 for trunk/dll/comp.c
- Timestamp:
- Jan 6, 2008, 8:26:17 AM (18 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/dll/comp.c
r897 r907 7 7 8 8 Copyright (c) 1993-02 M. Kimes 9 Copyright (c) 2003, 200 7Steven H. Levine9 Copyright (c) 2003, 2008 Steven H. Levine 10 10 11 11 16 Oct 02 MK Baseline … … 40 40 27 Sep 07 SHL Correct ULONGLONG size formatting 41 41 30 Dec 07 GKY Use TestCDates for compare by file date/time 42 04 Jan 08 SHL Avoid traps if CM_ALLOCRECORD returns less that requested 43 05 Jan 08 SHL Use WM_TIMER for progress messaging 44 05 Jan 08 SHL Use ITIMER_DESC for hogging control 42 45 43 46 ***********************************************************************/ 47 48 #include <stdlib.h> 49 #include <string.h> 50 #include <share.h> 51 #include <io.h> 52 #include <process.h> // _beginthread 44 53 45 54 #define INCL_DOS … … 48 57 #define INCL_GPI 49 58 #define INCL_LONGLONG 50 #include <os2.h> 51 52 #include <stdio.h> 53 #include <stdlib.h> 54 #include <string.h> 55 #include <ctype.h> 56 #include <share.h> 57 #include <io.h> 58 #include <process.h> // _beginthread 59 60 #include "fm3dll.h" 59 61 60 #include "fm3dlg.h" 62 61 #include "fm3str.h" 62 #include "pathutil.h" // BldFullPathName 63 #include "filldir.h" // EmptyCnr... 64 #include "makelist.h" // AddToFileList... 65 #include "errutil.h" // Dos_Error... 66 #include "strutil.h" // GetPString 67 #include "tmrsvcs.h" // IsITimerExpired 68 #include "comp.h" 69 #include "fm3dll.h" 63 70 64 71 typedef struct … … 71 78 72 79 static PSZ pszSrcFile = __FILE__; 73 74 /**75 * Build full path name in callers buffer given directory76 * name and filename77 * @param pszPathName points to drive/directory if not NULL78 * @returns pointer to full path name in caller's buffer79 * @note OK for pszFullPathName and pszPathName to point to same buffer80 *81 */82 83 PSZ BldFullPathName(PSZ pszFullPathName, PSZ pszPathName, PSZ pszFileName)84 {85 UINT c = pszPathName ? strlen(pszPathName) : 0;86 if (c > 0) {87 memcpy(pszFullPathName, pszPathName, c);88 if (pszFullPathName[c - 1] != '\\')89 pszFullPathName[c++] = '\\';90 }91 strcpy(pszFullPathName + c, pszFileName);92 return pszFullPathName;93 }94 80 95 81 //=== SnapShot() Write directory tree to file and recurse if requested === … … 116 102 // 13 Aug 07 SHL fixme to report errors 117 103 if (!xDosFindFirst(mask, 118 104 &hdir, 119 105 FILE_NORMAL | FILE_DIRECTORY | 120 106 FILE_ARCHIVED | FILE_READONLY | FILE_HIDDEN | … … 450 436 MPFROM2SHORT(CMA_FIRST, CMA_ITEMORDER)); 451 437 438 WinStartTimer(hab, cmp->hwnd, ID_TIMER, 2000); 439 452 440 while (pci && (INT)pci != -1 && pciD && (INT)pciD != -1) { 453 441 … … 675 663 } // while 676 664 Abort: 665 WinStopTimer(hab, cmp->hwnd, ID_TIMER); 677 666 WinDestroyMsgQueue(hmq); 678 667 } 668 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID); 669 PostMsg(cmp->hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DESELECTALL, 0), MPVOID); 679 670 DecrThreadUsage(); 680 671 WinTerminate(hab); 681 672 } 682 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID);683 PostMsg(cmp->hwnd, WM_COMMAND, MPFROM2SHORT(IDM_DESELECTALL, 0), MPVOID);684 673 free(cmp); 685 674 } … … 707 696 IncrThreadUsage(); 708 697 priority_normal(); 698 WinStartTimer(hab, cmp->hwnd, ID_TIMER, 2000); 709 699 switch (cmp->action) { 710 700 case IDM_INVERT: … … 724 714 break; 725 715 } 716 WinStopTimer(hab, cmp->hwnd, ID_TIMER); 726 717 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID)) 727 718 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPFROMLONG(1L), MPVOID); … … 738 729 */ 739 730 740 static VOID FillDirList(CHAR *str, INT skiplen, BOOL recurse,741 FILELIST ***list, INT *numfiles, INT *numalloc)731 static VOID FillDirList(CHAR *str, UINT skiplen, BOOL recurse, 732 FILELIST ***list, UINT *pnumfiles, UINT *pnumalloc) 742 733 { 743 734 CHAR *enddir; … … 780 771 ulFindCnt = FilesToGet; 781 772 rc = xDosFindFirst(maskstr, &hDir, 782 773 FILE_NORMAL | FILE_READONLY | FILE_ARCHIVED | 783 774 FILE_SYSTEM | FILE_HIDDEN | 784 775 (recurse ? FILE_DIRECTORY : 0), … … 799 790 strlwr(pffbFile->achName); 800 791 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1); 801 FillDirList(maskstr, skiplen, recurse, list, numfiles,numalloc);792 FillDirList(maskstr, skiplen, recurse, list, pnumfiles, pnumalloc); 802 793 } 803 794 } … … 809 800 memcpy(enddir, pffbFile->achName, pffbFile->cchName + 1); 810 801 if (AddToFileList(maskstr + skiplen, 811 pffbFile, list, numfiles,numalloc)) {802 pffbFile, list, pnumfiles, pnumalloc)) { 812 803 goto Abort; 813 804 } … … 847 838 } 848 839 849 // 20 Aug 07 SHL experimental fixme850 851 typedef struct {852 // Caller must init853 UINT sleepTime; // How long to sleep854 UINT interval; // How often to sleep855 // Owned by SleepIfNeeded856 UINT modulo; // How often to call GetMSecTimer857 UINT cntr; // Call counter858 ULONG lastMSec; // Last time DosSleep invoked859 } SLEEP_DESC;860 861 VOID SleepIfNeeded(BOOL id, UINT interval, UINT sleepTime)862 {863 static ULONG lastMSec[10];864 static UINT cntr;865 static UINT modulo = 32;866 BOOL yes = ++cntr >= modulo;867 868 if (yes) {869 ULONG newMSec = GetMSecTimer();870 // 1st time will have large difference, but don't care871 ULONG diff = newMSec - lastMSec[id];872 cntr = 0;873 yes = diff >= interval;874 // Try to tune modulo counter to approx 12% error875 if (yes) {876 lastMSec[id] = newMSec;877 if (diff >= interval + (interval / 8) && modulo > 0)878 modulo--;879 }880 else {881 if (diff < interval - (interval / 8))882 modulo++;883 }884 DosSleep(sleepTime);885 }886 }887 888 840 //=== FillCnrsThread() Fill left and right containers === 889 841 … … 894 846 HMQ hmq; 895 847 BOOL notified = FALSE; 896 897 #if 0 898 ULONG lastMSec = GetMSecTimer(); 899 ULONG ul; 900 #endif 848 ITIMER_DESC itdSleep = { 0 }; 901 849 902 850 HWND hwndLeft, hwndRight; … … 912 860 913 861 DosError(FERR_DISABLEHARDERR); 862 863 InitITimer(&itdSleep, 500); // Sleep every 500 mSec 914 864 915 865 hab = WinInitialize(0); … … 923 873 else { 924 874 INT x; 925 INT l;926 INT r;875 UINT l; 876 UINT r; 927 877 UINT cntr; 928 878 FILELIST **filesl = NULL; 929 879 FILELIST **filesr = NULL; 930 INT numfilesl = 0;931 INT numfilesr = 0;932 INT numallocl = 0;933 INT numallocr = 0;880 UINT numfilesl = 0; 881 UINT numfilesr = 0; 882 UINT numallocl = 0; 883 UINT numallocr = 0; 934 884 INT ret = 0; 935 885 UINT lenl; // Directory prefix length 936 886 UINT lenr; 937 887 UINT recsNeeded; 888 UINT recsGotten; 889 UINT filesSeenL; 890 UINT filesSeenR; 938 891 PCNRITEM pcilFirst; 939 892 PCNRITEM pcirFirst; 893 PCNRITEM pcilLast; 894 PCNRITEM pcirLast; 940 895 PCNRITEM pcil; 941 896 PCNRITEM pcir; … … 945 900 WinCancelShutdown(hmq, TRUE); 946 901 IncrThreadUsage(); 902 WinStartTimer(hab, cmp->hwnd, ID_TIMER, 2000); 903 947 904 hwndLeft = WinWindowFromID(cmp->hwnd, COMP_LEFTDIR); 948 905 hwndRight = WinWindowFromID(cmp->hwnd, COMP_RIGHTDIR); … … 965 922 strupr(cmp->leftdir); 966 923 FillDirList(cmp->leftdir, lenl, cmp->includesubdirs, 967 &filesl, &numfilesl, &numallocl); 924 &filesl, &cmp->cmp->totalleft, &numallocl); 925 numfilesl = cmp->cmp->totalleft; 968 926 969 927 if (filesl) … … 979 937 strupr(cmp->rightdir); 980 938 FillDirList(cmp->rightdir, lenr, cmp->includesubdirs, 981 &filesr, &numfilesr, &numallocr); 939 &filesr, &cmp->cmp->totalright, &numallocr); 940 numfilesr = cmp->cmp->totalright; 982 941 } 983 942 else { … … 1144 1103 } // while 1145 1104 1105 // Say building list - fixme to post? 1146 1106 WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID); 1147 1107 … … 1178 1138 pcil = pcilFirst; 1179 1139 pcir = pcirFirst; 1140 pcilLast = 0; 1141 pcirLast = 0; 1142 1143 recsGotten = 0; 1144 filesSeenL = 0; 1145 filesSeenR = 0; 1146 1180 1147 while ((filesl && filesl[l]) || (filesr && filesr[r])) { 1148 1149 // 03 Jan 08 SHL fixme to have user friendly message 1150 if (!pcil) { 1151 Runtime_Error(pszSrcFile, __LINE__, "pcil short %u/%u", 1152 recsGotten, recsNeeded); 1153 break; 1154 } 1155 1156 // 03 Jan 08 SHL fixme to have user friendly message 1157 if (!pcir) { 1158 Runtime_Error(pszSrcFile, __LINE__, "pcir short %u/%u", 1159 recsGotten, recsNeeded); 1160 break; 1161 } 1162 recsGotten++; 1181 1163 pcir->hwndCnr = hwndRight; 1182 1164 pcir->rc.hptrIcon = (HPOINTER) 0; … … 1195 1177 if (x <= 0) { 1196 1178 // File appears on left side 1179 filesSeenL++; 1197 1180 BldFullPathName(szBuf, cmp->leftdir, filesl[l]->fname); 1198 1181 //sprintf(szBuf, "%s%s%s", cmp->leftdir, … … 1233 1216 if (x >= 0) { 1234 1217 // File appears on right side 1218 filesSeenR++; 1235 1219 BldFullPathName(szBuf, cmp->rightdir, filesr[r]->fname); 1236 1220 //sprintf(szBuf, "%s%s%s", cmp->rightdir, … … 1291 1275 strcpy(pch, GetPString(IDS_SMALLERTEXT)); 1292 1276 pch += 7; 1293 1294 1295 1296 1297 1277 } 1278 ret = TestCDates(&pcir->date, &pcir->time, 1279 &pcil->date, &pcil->time); 1280 if (ret == 1) 1281 /*((pcil->date.year > pcir->date.year) ? TRUE : 1298 1282 (pcil->date.year < pcir->date.year) ? FALSE : 1299 1283 (pcil->date.month > pcir->date.month) ? TRUE : … … 1316 1300 pch += 5; 1317 1301 } 1318 1319 1302 else if (ret == -1) 1303 /*((pcil->date.year < pcir->date.year) ? TRUE : 1320 1304 (pcil->date.year > pcir->date.year) ? FALSE : 1321 1305 (pcil->date.month < pcir->date.month) ? TRUE : … … 1382 1366 pcir->pszDispAttr = NullStr; 1383 1367 1384 #if 0 // 20 Aug 07 SHL fixme to be gone 1385 if (!(cntr % 500)) 1386 DosSleep(1); 1387 else if (!(cntr % 50)) 1388 DosSleep(0); 1389 cntr++; 1390 #endif 1391 #if 0 // 20 Aug 07 SHL 1392 if (cntr++ % 256 == 0) { 1393 ul = GetMSecTimer(); 1394 if (ul - lastMSec >= 200) { 1395 lastMSec = ul; 1396 DosSleep(1); 1397 } 1398 } 1399 #endif 1400 #if 1 // 20 Aug 07 SHL 1401 SleepIfNeeded(0, 500, 1); 1402 #endif 1403 1368 // Avoid hogging systems 1369 SleepIfNeeded(&itdSleep, 0); 1370 1371 pcilLast = pcil; 1372 pcirLast = pcir; 1404 1373 pcil = (PCNRITEM) pcil->rc.preccNextRecord; 1405 1374 pcir = (PCNRITEM) pcir->rc.preccNextRecord; 1406 1375 1376 // Show running totals every 2 seconds 1377 cmp->cmp->totalleft = filesSeenL; 1378 cmp->cmp->totalright = filesSeenR; 1379 1407 1380 } // while filling left or right 1381 1382 // If stopped early CM_ALLOCATERECORD partially failed 1383 // Free up container records we did not use on other side 1384 // Free up filesl/filer entries we skipped 1385 if (recsGotten < recsNeeded) { 1386 if (pcil) { 1387 pcilLast->rc.preccNextRecord = NULL; 1388 FreeCnrItemList(hwndLeft, pcil); 1389 } 1390 if (filesl) { 1391 while (filesl[l]) { 1392 free(filesl[l]); 1393 l++; 1394 } 1395 } 1396 if (pcir) { 1397 pcirLast->rc.preccNextRecord = NULL; 1398 FreeCnrItemList(hwndRight, pcir); 1399 } 1400 if (filesr) { 1401 while (filesr[r]) { 1402 free(filesr[r]); 1403 r++; 1404 } 1405 } 1406 // Reduce counts to match what is in container 1407 if (numfilesl > filesSeenL) 1408 numfilesl = filesSeenL; 1409 if (numfilesr > filesSeenR) 1410 numfilesr = filesSeenR; 1411 recsNeeded = recsGotten; 1412 } // if insufficient resources 1413 1408 1414 1409 1415 if (filesl) … … 1413 1419 free(filesr); 1414 1420 filesr = NULL; 1415 // Insert 'em 1421 1422 // Say inserting 1416 1423 WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID); 1417 1424 1425 // Insert left side 1418 1426 memset(&ri, 0, sizeof(RECORDINSERT)); 1419 1427 ri.cb = sizeof(RECORDINSERT); … … 1430 1438 } 1431 1439 1440 // Insert right side 1432 1441 memset(&ri, 0, sizeof(RECORDINSERT)); 1433 1442 ri.cb = sizeof(RECORDINSERT); … … 1453 1462 } // if recsNeeded 1454 1463 1464 WinStopTimer(hab, cmp->hwnd, ID_TIMER); 1465 1455 1466 Deselect(hwndLeft); 1456 1467 Deselect(hwndRight); … … 1458 1469 // DbgMsg(pszSrcFile, __LINE__, "FillCnrsThread deselected"); 1459 1470 1471 // Request window update 1460 1472 if (!PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID)) 1461 1473 WinSendMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID); … … 1470 1482 1471 1483 WinDestroyMsgQueue(hmq); 1472 } 1484 } // if have queue 1485 if (!notified) 1486 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID); 1473 1487 DecrThreadUsage(); 1474 1488 WinTerminate(hab); 1475 1489 } 1476 if (!notified)1477 PostMsg(cmp->hwnd, UM_CONTAINER_FILLED, MPVOID, MPVOID);1478 1490 free(cmp); 1479 1491 DosPostEventSem(CompactSem); … … 1485 1497 #define hwndLeft (WinWindowFromID(hwnd,COMP_LEFTDIR)) 1486 1498 #define hwndRight (WinWindowFromID(hwnd,COMP_RIGHTDIR)) 1487 1488 // 20 Aug 07 SHL fixme experimental1489 1490 BOOL NeedGUIUpdate(BOOL id)1491 {1492 static ULONG lastMSec[10];1493 static UINT cntr;1494 static UINT modulo = 32;1495 BOOL yes = ++cntr >= modulo;1496 1497 if (yes) {1498 ULONG newMSec = GetMSecTimer();1499 // 1st time will have large difference, but don't care1500 ULONG diff = newMSec - lastMSec[id];1501 cntr = 0;1502 yes = diff >= 500;1503 // Try to tune modulo counter to 10% error1504 if (yes) {1505 lastMSec[id] = newMSec;1506 if (diff >= 550 && modulo > 0)1507 modulo--;1508 }1509 else {1510 if (diff < 450)1511 modulo++;1512 }1513 }1514 return yes;1515 }1516 1499 1517 1500 //=== CompareDlgProc() Compare directories dialog procedure === … … 1521 1504 COMPARE *cmp; 1522 1505 BOOL temp; 1506 CHAR s[81]; 1523 1507 1524 1508 static HPOINTER hptr; … … 1710 1694 1711 1695 case UM_CONTAINERHWND: 1696 // Building list 1712 1697 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDBLDLISTTEXT)); 1713 1698 return 0; 1714 1699 1715 1700 case UM_CONTAINERDIR: 1701 // Filling container 1716 1702 WinSetDlgItemText(hwnd, COMP_NOTE, GetPString(IDS_COMPHOLDFILLCNRTEXT)); 1717 1703 return 0; 1704 1705 case WM_TIMER: 1706 // Show current totals 1707 cmp = INSTDATA(hwnd); 1708 if (!cmp) { 1709 Runtime_Error(pszSrcFile, __LINE__, "pCompare NULL"); 1710 WinDismissDlg(hwnd, 0); 1711 } 1712 else { 1713 // 05 Jan 08 SHL fixme to use timer id to optimize output 1714 sprintf(s, " %d", cmp->totalleft); 1715 WinSetDlgItemText(hwnd, COMP_TOTALLEFT, s); 1716 sprintf(s, " %d", cmp->totalright); 1717 WinSetDlgItemText(hwnd, COMP_TOTALRIGHT, s); 1718 sprintf(s, " %d", cmp->selleft); 1719 WinSetDlgItemText(hwnd, COMP_SELLEFT, s); 1720 sprintf(s, " %d", cmp->selright); 1721 WinSetDlgItemText(hwnd, COMP_SELRIGHT, s); 1722 } 1723 break; 1718 1724 1719 1725 case UM_CONTAINER_FILLED: … … 1724 1730 } 1725 1731 else { 1726 CHAR s[81];1727 1732 1728 1733 // DbgMsg(pszSrcFile, __LINE__, "CompareDlgProc UM_CONTAINER_FILLED enter"); … … 1938 1943 else { 1939 1944 1940 CHAR s[81];1941 1942 1945 cmp = INSTDATA(hwnd); 1943 1946 if (pci->rc.flRecordAttr & CRA_SELECTED) { … … 1955 1958 if (cmp->selright) 1956 1959 cmp->selright--; 1957 }1958 }1959 if (SHORT1FROMMP(mp1) == COMP_LEFTDIR) {1960 // if (WinIsWindowEnabled(hwndLeft) || !(cmp->selleft % 50)) {1961 if (WinIsWindowEnabled(hwndLeft) || NeedGUIUpdate(0)) {1962 sprintf(s, " %d", cmp->selleft);1963 WinSetDlgItemText(hwnd, COMP_SELLEFT, s);1964 }1965 }1966 else {1967 // if (WinIsWindowEnabled(hwndRight) || !(cmp->selright % 50)) {1968 if (WinIsWindowEnabled(hwndRight) || NeedGUIUpdate(1)) {1969 sprintf(s, " %d", cmp->selright);1970 WinSetDlgItemText(hwnd, COMP_SELRIGHT, s);1971 1960 } 1972 1961 } … … 2180 2169 fakelist[2] = NULL; 2181 2170 ExecOnList(hwnd, compare, 2182 2183 2171 WINDOWED | SEPARATEKEEP, NULL, fakelist, NULL, 2172 pszSrcFile, __LINE__); 2184 2173 } 2185 2174 else {
Note:
See TracChangeset
for help on using the changeset viewer.