Changeset 1563 for trunk/dll/comp.c


Ignore:
Timestamp:
May 30, 2011, 9:21:53 PM (14 years ago)
Author:
Steven Levine
Message:

Rework collector and compare directories to correctly support more than 65K records.
Collector was trapping.
Compare directories was fixed to avoid the traps, but the implementation was not correctly handling all records.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/dll/comp.c

    r1545 r1563  
    7575  17 JAN 10 GKY Changes to get working with Watcom 1.9 Beta (1/16/10). Mostly cast CHAR CONSTANT * as CHAR *.
    7676  23 Oct 10 GKY Add ForwardslashToBackslash function to streamline code
     77  29 May 11 SHL Rework >65K records logic - prior fix was not quite right
    7778
    7879***********************************************************************/
     
    8384#include <io.h>
    8485#include <ctype.h>
     86#include <limits.h>                     // USHRT_MAX
    8587
    8688#define INCL_DOS
     
    10671069          CHAR buf1[1024];
    10681070          CHAR buf2[1024];
    1069           HAB hab = WinQueryAnchorBlock(hwndCnrS);
    1070           CHAR *moderb = "rb";
     1071          HAB hab = WinQueryAnchorBlock(hwndCnrS);
     1072          CHAR *moderb = "rb";
    10711073
    10721074          if (!*pciS->pszFileName ||
     
    15031505      UINT numallocl = 0;
    15041506      UINT numallocr = 0;
    1505       INT ret = 0;
    15061507      UINT lenl;                        // Directory prefix length
    15071508      UINT lenr;
    1508       UINT recsNeeded;
    1509       UINT recsGotten;
    1510       PCNRITEM pcilFirst;
    1511       PCNRITEM pcirFirst;
    1512       PCNRITEM pcilLast;
    1513       PCNRITEM pcirLast;
    1514       PCNRITEM pcil;
    1515       PCNRITEM pcir;
    1516       RECORDINSERT ri;
     1509      ULONG ulRecsNeeded;
    15171510      CHAR *pch;
    15181511      HWND hwndLeft;
     
    15611554        FILE *fp;
    15621555        FILEFINDBUF4L fb4;
    1563         CHAR str[CCHMAXPATH * 2], *p;
    1564         CHAR *moder = "r";
     1556        CHAR str[CCHMAXPATH * 2], *p;
     1557        CHAR *moder = "r";
    15651558
    15661559        memset(&fb4, 0, sizeof(fb4));
     
    16971690      // We now have two lists of files, both sorted.
    16981691      // Count total number of container entries required on each side
    1699       l = r = 0;
    1700       recsNeeded = 0;
     1692      l = 0;
     1693      r = 0;
     1694      ulRecsNeeded = 0;
    17011695      while ((filesl && filesl[l]) || (filesr && filesr[r])) {
    17021696
     
    17181712          r++;                          // On right side
    17191713
    1720         recsNeeded++;                   // Keep count of how many entries req'd
    1721 
    1722       } // while
    1723 
    1724       if (cmp->stop) {
    1725         recsNeeded = 0;
    1726       }
    1727 
    1728       // Now insert records into the containers
    1729 
    1730       if (recsNeeded) {
     1714        ulRecsNeeded++;                 // Count how many entries req'd
     1715
     1716      } // while counting
     1717
     1718      if (cmp->stop)
     1719        ulRecsNeeded = 0;
     1720
     1721      // Insert records into the containers
     1722
     1723      if (ulRecsNeeded) {
     1724
     1725        PCNRITEM pcilFirst;
     1726        PCNRITEM pcirFirst;
     1727        PCNRITEM pcil = NULL;
     1728        PCNRITEM pcir = NULL;
     1729        INT ret;
     1730        ULONG ulRecsAllocated = 0;
     1731        ULONG insertedl;
     1732        ULONG insertedr;
     1733
     1734        l = 0;
     1735        r = 0;
    17311736
    17321737        // Use send to get message on screen quickly
    17331738        WinSendMsg(cmp->hwnd, UM_CONTAINERHWND, MPVOID, MPVOID);
    17341739
    1735         pcilFirst = WinSendMsg(hwndLeft,
    1736                                CM_ALLOCRECORD,
    1737                                MPFROMLONG(EXTRA_RECORD_BYTES),
    1738                                MPFROMLONG(recsNeeded));
    1739         if (!pcilFirst) {
    1740           Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
    1741           recsNeeded = 0;
    1742         }
    1743       }
    1744 
    1745       if (recsNeeded) {
    1746         pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
    1747                                MPFROMLONG(EXTRA_RECORD_BYTES),
    1748                                MPFROMLONG(recsNeeded));
    1749         if (!pcirFirst) {
    1750           Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
    1751           recsNeeded = 0;
    1752           FreeCnrItemList(hwndLeft, pcilFirst);
    1753         }
    1754       }
    1755 
    1756       if (recsNeeded) {
    1757 
    1758         l = 0;
    1759         r = 0;
    1760         pcil = pcilFirst;
    1761         pcir = pcirFirst;
    1762         pcilLast = NULL;
    1763         pcirLast = NULL;
    1764 
    1765         recsGotten = 0;
    17661740        cmp->cmp->totalleft = 0;
    17671741        cmp->cmp->totalright = 0;
     
    17691743        while ((filesl && filesl[l]) || (filesr && filesr[r])) {
    17701744
     1745          ULONG ulRecsToInsert; // limited to USHRT_MAX
     1746
    17711747          if (cmp->stop)
    17721748            break;
    17731749
    1774           if (!pcil) {
    1775             Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_INSUFFICIENTMEMORY),
    1776                           recsNeeded, recsGotten);
    1777             break;
    1778           }
    1779 
    1780           if (!pcir) {
    1781             Runtime_Error(pszSrcFile, __LINE__, GetPString(IDS_INSUFFICIENTMEMORY),
    1782                           recsNeeded, recsGotten);
    1783             break;
    1784           }
    1785           recsGotten++;
     1750          // Check alloc needed
     1751          if (!pcil || !pcir) {
     1752            if (pcil != pcir) {
     1753              // 2011-05-29 SHL fixme to GetPString
     1754              Runtime_Error(pszSrcFile, __LINE__, "pcil and pcir out of sync");
     1755              cmp->stop = TRUE;
     1756              break;
     1757            }
     1758            ulRecsToInsert = ulRecsNeeded - ulRecsAllocated;
     1759            if (ulRecsToInsert > USHRT_MAX)
     1760              ulRecsToInsert = USHRT_MAX;
     1761
     1762            pcilFirst = WinSendMsg(hwndLeft,
     1763                                   CM_ALLOCRECORD,
     1764                                   MPFROMLONG(EXTRA_RECORD_BYTES),
     1765                                   MPFROMLONG(ulRecsToInsert));
     1766            if (!pcilFirst) {
     1767              Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
     1768              cmp->stop = TRUE;
     1769              break;
     1770            }
     1771            pcirFirst = WinSendMsg(hwndRight, CM_ALLOCRECORD,
     1772                                   MPFROMLONG(EXTRA_RECORD_BYTES),
     1773                                   MPFROMLONG(ulRecsToInsert));
     1774            if (!pcirFirst) {
     1775              Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, PCSZ_CM_ALLOCRECORD);
     1776              FreeCnrItemList(hwndLeft, pcilFirst);
     1777              pcilFirst = NULL;
     1778              cmp->stop = TRUE;
     1779              break;
     1780            }
     1781            pcil = pcilFirst;
     1782            pcir = pcirFirst;
     1783            insertedl = 0;
     1784            insertedr = 0;
     1785            ulRecsAllocated += ulRecsToInsert;
     1786          } // if need alloc
     1787
    17861788          pcir->hwndCnr = hwndRight;
    17871789          pcir->rc.hptrIcon = (HPOINTER)0;
     
    18011803            // File appears on left side
    18021804            cmp->cmp->totalleft++;
     1805            insertedl++;
    18031806            BldFullPathName(szBuf, cmp->leftdir, filesl[l]->fname);
    18041807            pcil->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);
     
    18401843            // File appears on right side
    18411844            cmp->cmp->totalright++;
     1845            insertedr++;
    18421846            BldFullPathName(szBuf, cmp->rightdir, filesr[r]->fname);
    18431847            pcir->pszFileName = xstrdup(szBuf, pszSrcFile, __LINE__);   // 31 Jul 07 SHL
     
    19271931          } // if on both sides
    19281932
    1929           if (x <= 0) {
     1933          if (x <= 0)
    19301934            free(filesl[l++]);          // Done with item on left
    1931           }
    1932           if (x >= 0) {
     1935
     1936          if (x >= 0)
    19331937            free(filesr[r++]);          // Done with item on right
    1934           }
     1938
    19351939          // Ensure empty buffers point somewhere
    19361940          if (!pcil->pszFileName) {
     
    19621966          SleepIfNeeded(&itdSleep, 0);
    19631967
    1964           pcilLast = pcil;
    1965           pcirLast = pcir;
    19661968          pcil = (PCNRITEM)pcil->rc.preccNextRecord;
    19671969          pcir = (PCNRITEM)pcir->rc.preccNextRecord;
    19681970
     1971          if (pcil == NULL || pcir == NULL) {
     1972            RECORDINSERT ri;
     1973            if (pcil != pcir) {
     1974              Runtime_Error(pszSrcFile, __LINE__, "pcil and pcir out of sync");
     1975              cmp->stop = TRUE;
     1976              break;
     1977            }
     1978            // Say inserting
     1979            WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
     1980
     1981            // Insert left side
     1982            memset(&ri, 0, sizeof(RECORDINSERT));
     1983            ri.cb = sizeof(RECORDINSERT);
     1984            ri.pRecordOrder = (PRECORDCORE)CMA_END;
     1985            ri.pRecordParent = (PRECORDCORE)NULL;
     1986            ri.zOrder = (ULONG)CMA_TOP;
     1987            ri.cRecordsInsert = ulRecsToInsert;
     1988            ri.fInvalidateRecord = FALSE;
     1989
     1990            if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
     1991                            MPFROMP(pcilFirst), MPFROMP(&ri))) {
     1992              Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
     1993              FreeCnrItemList(hwndLeft, pcilFirst);
     1994              cmp->cmp->totalleft -= insertedl;
     1995            }
     1996            pcilFirst = NULL;
     1997
     1998            // Insert right side
     1999            memset(&ri, 0, sizeof(RECORDINSERT));
     2000            ri.cb = sizeof(RECORDINSERT);
     2001            ri.pRecordOrder = (PRECORDCORE)CMA_END;
     2002            ri.pRecordParent = (PRECORDCORE)NULL;
     2003            ri.zOrder = (ULONG)CMA_TOP;
     2004            ri.cRecordsInsert = ulRecsToInsert;
     2005            ri.fInvalidateRecord = FALSE;
     2006
     2007            if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
     2008                            MPFROMP(pcirFirst), MPFROMP(&ri))) {
     2009              Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
     2010              // 2011-05-29 SHL fixme?
     2011              RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
     2012              FreeCnrItemList(hwndRight, pcirFirst);
     2013              cmp->cmp->totalright -= insertedr;
     2014            }
     2015            pcirFirst = NULL;
     2016          } // if need insert
     2017
    19692018        } // while filling left or right
    19702019
    1971         // If stopped early CM_ALLOCATERECORD partially failed
    1972         // Free up container records we did not use on other side
    1973         // Free up items we did not insert in container
    1974         if (recsGotten < recsNeeded) {
    1975           if (pcil) {
    1976             if (pcilLast)
    1977               pcilLast->rc.preccNextRecord = NULL;
    1978             else
    1979               pcilFirst = NULL;
    1980             FreeCnrItemList(hwndLeft, pcil);
    1981           }
     2020        // If stopped early clean up
     2021
     2022        if (cmp->stop) {
     2023          // Free up container records that we did not insert in container
     2024          if (pcilFirst)
     2025            FreeCnrItemList(hwndLeft, pcilFirst);
     2026
     2027          // Free up items we did not insert in container
    19822028          if (filesl) {
    19832029            for(; filesl[l]; l++) {
     
    19852031            }
    19862032          }
    1987           if (pcir) {
    1988             if (pcirLast)
    1989               pcirLast->rc.preccNextRecord = NULL;
    1990             else
    1991               pcirFirst = NULL;
    1992             FreeCnrItemList(hwndRight, pcir);
    1993           }
     2033
     2034          if (pcirFirst)
     2035            FreeCnrItemList(hwndRight, pcirFirst);
     2036
    19942037          if (filesr) {
    19952038            for (; filesr[r]; r++) {
     
    19972040            }
    19982041          }
    1999           // Reduce count to match what is in containers
    2000           recsNeeded = recsGotten;
    20012042        } // if insufficient resources
    20022043
    2003           xfree(filesl, pszSrcFile, __LINE__);  // Free header - have already freed elements
     2044        xfree(filesl, pszSrcFile, __LINE__);    // Free header - have already freed elements
    20042045        filesl = NULL;
    20052046          xfree(filesr, pszSrcFile, __LINE__);
    20062047        filesr = NULL;
    20072048
    2008         // Say inserting
    2009         WinSendMsg(cmp->hwnd, UM_CONTAINERDIR, MPVOID, MPVOID);
    2010 
    2011         // Insert left side
    2012         memset(&ri, 0, sizeof(RECORDINSERT));
    2013         ri.cb = sizeof(RECORDINSERT);
    2014         ri.pRecordOrder = (PRECORDCORE)CMA_END;
    2015         ri.pRecordParent = (PRECORDCORE)NULL;
    2016         ri.zOrder = (ULONG)CMA_TOP;
    2017         ri.cRecordsInsert = recsNeeded;
    2018         ri.fInvalidateRecord = FALSE;
    2019 
    2020         if (!WinSendMsg(hwndLeft, CM_INSERTRECORD,
    2021                         MPFROMP(pcilFirst), MPFROMP(&ri))) {
    2022           Win_Error(hwndLeft, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
    2023           FreeCnrItemList(hwndLeft, pcilFirst);
    2024           cmp->cmp->totalleft = 0;
    2025         }
    2026 
    2027         // Insert right side
    2028         memset(&ri, 0, sizeof(RECORDINSERT));
    2029         ri.cb = sizeof(RECORDINSERT);
    2030         ri.pRecordOrder = (PRECORDCORE)CMA_END;
    2031         ri.pRecordParent = (PRECORDCORE)NULL;
    2032         ri.zOrder = (ULONG)CMA_TOP;
    2033         ri.cRecordsInsert = recsNeeded;
    2034         ri.fInvalidateRecord = FALSE;
    2035 
    2036         if (!WinSendMsg(hwndRight, CM_INSERTRECORD,
    2037                         MPFROMP(pcirFirst), MPFROMP(&ri))) {
    2038           Win_Error(hwndRight, cmp->hwnd, pszSrcFile, __LINE__, "CM_INSERTRECORD");
    2039           RemoveCnrItems(hwndLeft, NULL, 0, CMA_FREE | CMA_INVALIDATE);
    2040           FreeCnrItemList(hwndRight, pcirFirst);
    2041           cmp->cmp->totalright = 0;
    2042         }
    2043 
    2044       } // if recsNeeded
     2049      } // if ulRecsNeeded
    20452050
    20462051      Deselect(hwndLeft);
     
    28302835            fakelist[1] = szPathName;
    28312836            fakelist[2] = NULL;
    2832             ExecOnList(hwnd, compare, WINDOWED | SEPARATEKEEP,
    2833                        NULL, NULL, fakelist, NULL,
     2837            ExecOnList(hwnd, compare, WINDOWED | SEPARATEKEEP,
     2838                       NULL, NULL, fakelist, NULL,
    28342839                       pszSrcFile, __LINE__);
    28352840          }
Note: See TracChangeset for help on using the changeset viewer.