#include #include #include "junk.h" #include "load.h" #include "mem.h" #include "rerror.h" #include "size.h" #define NMAXREAD 65500 // close to _lread max char lpTemp[256]; // temp string for '.dif' filename void SetDiffFileName(void); BYTE FindMeAFileDataIndex(void); BYTE BuildLineList(void); BYTE BuildSingleLineList(void); BYTE MyReadFile(void); BYTE ReadDiff(void); WORD ReadScompNums(HFILE hf, BYTE _huge* NEAR* lpPos, int ch); void ReadScompDeadLines(HFILE hf, int nLines, int ch); void ReadScompCenter(HFILE hf); void ReadScompLines(HFILE hf, UINT nLines, BYTE _huge* NEAR* lpPos, int ch); void ReadScompHeader(HFILE hf, BYTE iFile); void GetDiffValues(BYTE _huge* NEAR* lpDiffPos, BYTE *ch, WORD *lb, WORD *le, WORD *rb, WORD *re, WORD wSet); /**************************************************************************/ BYTE ReadThisFile(LPSTR lpstrFile) { BYTE FAR* lp; BYTE ret; int i; if (all.iFile != NMAXFILES) UnlockMemoryChunk(all.iFile); all.iFile = FindMeAFileDataIndex(); all.nFiles++; lp = all.lpFileData[all.iFile].lpName; for (i=0; lpstrFile[i]; i++) lp[i] = lpstrFile[i]; lp[i] = 0; while ((lp[i] != '\\') && i) // check for beginning or '\\' i--; if (lp[i] == '\\') i++; all.lpFileData[all.iFile].lpNameOff = i; ret = MyReadFile(); // fails if no memory or file does not open if (!ret) { all.nFiles--; return 0; } SetDiffFileName(); ret = ReadDiff(); // ret: 0=no mem; 1=no file or success if (!ret) { FreeMemoryChunk(all.iFile, GMC_FILE); // free hFile all.nFiles--; return 0; } if (all.lpFileData[all.iFile].hDiff) { ret = BuildLineList(); // fails if no memory if (!ret) { FreeMemoryChunk(all.iFile, GMC_FILE); FreeMemoryChunk(all.iFile, GMC_DIFF); all.nFiles--; return 0; } else all.lpFileData[all.iFile].bits = FD_DIFF; } else { ret = BuildSingleLineList(); // fails if no memory if (!ret) { FreeMemoryChunk(all.iFile, GMC_FILE); all.nFiles--; return 0; } else all.lpFileData[all.iFile].bits = FD_SINGLE; } return 1; } /**************************************************************************/ BYTE BuildLineList(void) { LINELISTSTRUCT _huge* hp; BYTE _huge* hpFilePos; BYTE _huge* hpDiffPos; BYTE ret; DWORD dwSize; WORD wOldILine; // needed to mark beginings of diff blocks WORD tlines; // total number of lines WORD iline; WORD lline, rline, lb, le, rb, re; BYTE ch; WORD i, clmax; tlines = all.lpFileData[all.iFile].nLines + all.lpFileData[all.iFile].nDLines; all.lpFileData[all.iFile].nTLines = tlines; dwSize = sizeof(LINELISTSTRUCT) * (DWORD)(tlines + 1); /* LLS structure is aligned in 64k so nothing special needed. */ ret = GetMemoryChunk(all.iFile, GMC_LINES, dwSize); if (!ret) { XXX("\n\rLOAD:BuildLineList:GetMemoryChunk failed."); return 0; } hp = (LINELISTSTRUCT _huge*) all.lpFileData[all.iFile].hpLines; hpFilePos = all.lpFileData[all.iFile].hpFile; hpDiffPos = all.lpFileData[all.iFile].hpDiff; iline = 0; // total lines; index for hp lline = 0; // left line index rline = 0; // right line index GetDiffValues(&hpDiffPos, &ch, &lb, &le, &rb, &re, 0); // 0 clears a static while (iline < tlines) { if ((ch == 'a') && (lline == lb)) { wOldILine = iline; for (i=rb; i<=re; i++) { hp[iline].nlchars = 0; hp[iline].nrchars = *hpFilePos; hpFilePos++; hp[iline].lpl = 0; hp[iline].lpr = (BYTE FAR*) hpFilePos; hp[iline].flags = LLS_A; hpFilePos += hp[iline].nrchars; //if (LOWORD(hpFilePos) > MYENDSEG) // hpFilePos += (~LOWORD(hpFilePos) + 1); hp[iline].nrchars--; // carriage returns iline++; rline++; } hp[wOldILine].flags |= LLS_NDIFF; GetDiffValues(&hpDiffPos, &ch, &lb, &le, &rb, &re, 1); } else if ((ch == 'd') && (rline == rb)) { wOldILine = iline; for (i=lb; i<=le; i++) { hp[iline].nlchars = *hpDiffPos; hp[iline].nrchars = 0; hpDiffPos++; hp[iline].lpl = (BYTE FAR*) hpDiffPos; hp[iline].lpr = 0; hp[iline].flags = LLS_D; hpDiffPos += hp[iline].nlchars; //if (LOWORD(hpDiffPos) > MYENDSEG) // hpDiffPos += (~LOWORD(hpDiffPos) + 1); hp[iline].nlchars--; // carriage returns iline++; lline++; } hp[wOldILine].flags |= LLS_NDIFF; GetDiffValues(&hpDiffPos, &ch, &lb, &le, &rb, &re, 1); } else if ((ch == 'c') && (lline + 1 == lb)) { clmax = max(le - lb, re - rb); wOldILine = iline; for (i=0; i<=clmax; i++) { if (lb + i <= le) { hp[iline].nlchars = *hpDiffPos; hpDiffPos++; hp[iline].lpl = (BYTE FAR*) hpDiffPos; hp[iline].flags = LLS_CL; hpDiffPos += hp[iline].nlchars; //if (LOWORD(hpDiffPos) > MYENDSEG) // hpDiffPos += (~LOWORD(hpDiffPos) + 1); hp[iline].nlchars--; // carriage returns lline++; } else { hp[iline].nlchars = 0; hp[iline].lpl = 0; hp[iline].flags = 0; } if (rb + i <= re) { hp[iline].nrchars = *hpFilePos; hpFilePos++; hp[iline].lpr = (BYTE FAR*) hpFilePos; hp[iline].flags |= LLS_CR; hpFilePos += hp[iline].nrchars; //if (LOWORD(hpFilePos) > MYENDSEG) // hpFilePos += (~LOWORD(hpFilePos) + 1); hp[iline].nrchars--; // carriage returns rline++; } else { hp[iline].nrchars = 0; hp[iline].lpr = 0; // flags already established as 0. } iline++; } hp[wOldILine].flags |= LLS_NDIFF; GetDiffValues(&hpDiffPos, &ch, &lb, &le, &rb, &re, 1); } else { hp[iline].nlchars = *hpFilePos; // ??? RaymondC: *hpFilePos is bogus. hp[iline].nrchars = *hpFilePos; hpFilePos++; hp[iline].lpl = (BYTE FAR*) hpFilePos; hp[iline].lpr = (BYTE FAR*) hpFilePos; hp[iline].flags = 0; hpFilePos += hp[iline].nlchars; //if (LOWORD(hpFilePos) > MYENDSEG) // hpFilePos += (~LOWORD(hpFilePos) + 1); hp[iline].nlchars--; // carriage returns hp[iline].nrchars--; // carriage returns iline++; lline++; rline++; } } hp[tlines].lpl = 0; hp[tlines].lpr = 0; hp[tlines].nlchars = 0; hp[tlines].nrchars = 0; hp[tlines].flags = 0; return 1; } /**************************************************************************/ void GetDiffValues(BYTE _huge* NEAR* hpDiffPos, BYTE *ch, WORD *lb, WORD *le, WORD *rb, WORD *re, WORD wSet) { static int iCount; BYTE _huge* hp; if (wSet == 0) // We are beginning a new file and want to clear the iCount = 1; // number of diff blocks. else iCount++; // Increment the count of highlighted blocks. if (iCount > all.lpFileData[all.iFile].nDiffBlocks) { // return bogus values *ch = 0; } else { hp = *hpDiffPos; *ch = *hp++; *lb = *((WORD _huge*)hp); hp += 2; *le = *((WORD _huge*)hp); hp += 2; *rb = *((WORD _huge*)hp); hp += 2; *re = *((WORD _huge*)hp); hp += 2; *hpDiffPos = hp; } } /**************************************************************************/ BYTE BuildSingleLineList(void) { LINELISTSTRUCT _huge* hp; BYTE _huge* hpFilePos; BYTE ret; DWORD dwSize; int i; /* include space for a blank line at bottom of file. Good for */ /* printing the screen. */ all.lpFileData[all.iFile].nTLines = all.lpFileData[all.iFile].nLines; dwSize = sizeof(LINELISTSTRUCT) * (DWORD)(all.lpFileData[all.iFile].nLines + 1); ret = GetMemoryChunk(all.iFile, GMC_LINES, dwSize); if (!ret) { XXX("\n\rLOAD:BuildSingleLineList:GetMemoryChunk failed."); return 0; } hp = (LINELISTSTRUCT _huge*) all.lpFileData[all.iFile].hpLines; hpFilePos = all.lpFileData[all.iFile].hpFile; for (i=0; i MYENDSEG) // hpFilePos += (~LOWORD(hpFilePos) + 1); hp[i].nlchars--; // carriage return hp[i].nrchars--; // carriage return } hp[i].lpl = 0; hp[i].lpr = 0; hp[i].nlchars = 0; hp[i].nrchars = 0; hp[i].flags = 0; return 1; } /**************************************************************************/ BYTE MyReadFile(void) { BYTE _huge* hpPos; BYTE _huge* hpPosCount; DWORD dwSize; HFILE hf; WORD i,j; int ch; WORD fTooLong = 0; // Get the file length. dwSize = FindFileLength(all.lpFileData[all.iFile].lpName); if (!dwSize) return 0; // Lines may not cross 64k boundaries so must account for the buffer space. dwSize += (256 * ((dwSize >> 16) + 1)); // Allocate the memory. if (!GetMemoryChunk(all.iFile, GMC_FILE, dwSize)) return 0; hf = New_fopen(all.lpFileData[all.iFile].lpName); if (hf == HFILE_ERROR) { FreeMemoryChunk(all.iFile, GMC_FILE); return 0; } hpPosCount = all.lpFileData[all.iFile].hpFile; hpPos = hpPosCount + 1; i = 0; // number of lines j = 0; // chars per line while ((ch = New_getc(hf)) != EOF) { if (ch == '\n') { if (j > 255) { if (!fTooLong) { XXX("\n\rHOSED!!! line greater than 255 chars."); fTooLong = 1; } hpPos -= (j - 255); // put it back j = 255; } *hpPosCount = (BYTE)j; /* check if too close to end of a segment. */ //if (LOWORD(hpPos) > MYENDSEG) // hpPos += (~LOWORD(hpPos) + 1); hpPosCount = hpPos; hpPos++; i++; j = 0; } else { *hpPos++ = ch; j++; } } *hpPosCount = (BYTE)min((j + 1), 255); // VERY IMP!!! EOF has no carriage return. i++; // count the EOF line all.lpFileData[all.iFile].nLines = i; New_fclose(hf); YYY("\n\rLOAD:ReadFile -> %u lines", i); return 1; } /**************************************************************************/ BYTE ReadDiff(void) { BYTE _huge* hpPos; DWORD dwSize; HFILE hf; int ch; WORD nDLines; dwSize = FindFileLength(lpTemp); if (!dwSize) return 1; // only fail if no memory !!! dwSize += 2; /* We might need extra space because of segments. */ dwSize += (256 * (dwSize / 0xffff)); // add 256 for each segment if (!GetMemoryChunk(all.iFile, GMC_DIFF, dwSize)) return 0; hf = New_fopen(lpTemp); if (hf == HFILE_ERROR) { FreeMemoryChunk(all.iFile, GMC_DIFF); return 1; } hpPos = all.lpFileData[all.iFile].hpDiff; nDLines = 0; // lines to be added from diff while ((ch = New_getc(hf)) >= '0' && ch <= '9') { nDLines += ReadScompNums(hf, &hpPos, ch); all.lpFileData[all.iFile].nDiffBlocks++; // inc the # of blks } all.lpFileData[all.iFile].nDLines = nDLines; New_fclose(hf); return 1; } /**************************************************************************/ void MakeScompDirectory(void) { int i, j; j = -1; for (i=0; szScompFile[i]; i++) { szScompDir[i] = szScompFile[i]; if (szScompFile[i] == '\\') // track the last '\\' j = i; } szScompDir[j+1] = 0; // null terminated, clip off file } /**************************************************************************/ #define bEOF 1 // EOF was hit #define bNoFile 2 // No Files are left BYTE ReadScomp(HWND hwnd) { BYTE _huge* hpPos; DWORD dwSize; HFILE hf; BYTE curFile; BYTE bits = 0; int ch; WORD nDLines; BYTE ret; if (all.iFile != NMAXFILES) UnlockMemoryChunk(all.iFile); all.iFile = FindMeAFileDataIndex(); dwSize = FindFileLength(szScompFile); if (!dwSize) return 0; dwSize += 2; dwSize += (256 * (dwSize / 0xffff)); // add 256 for each segment if (!GetMemoryChunk(all.iFile, GMC_DIFF, dwSize)) return 0; hf = New_fopen(szScompFile); if (hf == HFILE_ERROR) { FreeMemoryChunk(all.iFile, GMC_DIFF); return 0; } curFile = all.iFile; hpPos = all.lpFileData[all.iFile].hpDiff; // good: isolated hpDiff while ((ch = New_getc(hf)) != '-' && ch != EOF); if (ch == EOF) bits |= bEOF; while (!bits) { all.nFiles++; // optimistic nDLines = 0; // diff lines to be added to this file all.lpFileData[curFile].hpDiff = hpPos; all.lpFileData[curFile].bits = FD_SCOMP; ReadScompHeader(hf, curFile); AddFileToMenu(curFile); while ((ch = New_getc(hf)) >= '0' && ch <= '9') { // stupid while !!! nDLines += ReadScompNums(hf, &hpPos, ch); all.lpFileData[curFile].nDiffBlocks++; // inc the # of blks } all.lpFileData[curFile].nDLines = nDLines; while ((ch = New_getc(hf)) != '-' && ch != EOF); if (ch == EOF) bits |= bEOF; curFile = FindMeAFileDataIndex(); if (all.nFiles == NMAXFILES) { MessageBox(hwnd, "The maximum number of files has been reached. Only part of the Scomp was loaded.", 0, MB_OK | MB_ICONEXCLAMATION); bits |= bNoFile; } } all.lpFileData[all.iFile].bits = FD_SCOMPWDIFF; // done after so not erased New_fclose(hf); ret = MyReadFile(); if (!ret) { /* maybe some major cleanup !!! ??? */ return 0; } ret = BuildLineList(); if (!ret) { /* maybe some major cleanup !!! ??? */ FreeMemoryChunk(all.iFile, GMC_FILE); return 0; } return 1; } /**************************************************************************/ WORD ReadScompNums(HFILE hf, BYTE _huge* NEAR* hpPos, int ch) { BYTE _huge* hp; WORD nDLines; WORD lb, le, rb, re; int chOp; lb = ch - '0'; while ((ch = New_getc(hf)) >= '0' && ch <= '9') lb = lb * 10 + ch - '0'; if (ch == ',') { le = 0; while ((ch = New_getc(hf)) >= '0' && ch <= '9') le = le * 10 + ch - '0'; } else le = lb; chOp = ch; // Store the character operation rb = 0; while ((ch = New_getc(hf)) >= '0' && ch <= '9') rb = rb * 10 + ch - '0'; if (ch == ',') { re = 0; while ((ch = New_getc(hf)) >= '0' && ch <= '9') re = re * 10 + ch - '0'; } else re = rb; if (ch == '\r') ch = New_getc(hf); if (ch != '\n') OutputDebugString("\n\rYour ReadScompNums isn't working very well!!"); XXX("\n\r"); YYY("%4i",lb); YYY("%4i",le); YYY(" %c ", chOp); YYY("%4i",rb); YYY("%4i",re); hp = *hpPos; *hp = chOp; hp++; *((WORD _huge*) hp) = lb; hp += 2; *((WORD _huge*) hp) = le; hp += 2; *((WORD _huge*) hp) = rb; hp += 2; *((WORD _huge*) hp) = re; hp += 2; *hpPos = hp; if (chOp == 'a') { nDLines = 0; ReadScompDeadLines(hf, re - rb + 1, ch); } else if (chOp == 'c') { if ((le - lb) > (re - rb)) nDLines = (le -lb) - (re - rb); else nDLines = 0; ReadScompLines(hf, le - lb + 1, hpPos, ch); ReadScompCenter(hf); ReadScompDeadLines(hf, re - rb + 1, ch); } else { nDLines = le - lb + 1; ReadScompLines(hf, le - lb + 1, hpPos, ch); } return nDLines; } /**************************************************************************/ void ReadScompDeadLines(HFILE hf, int nLines, int ch) { int i; for (i=0; i MYENDSEG) // *hpPos += (~LOWORD(*hpPos) + 1); hpPosCount = *hpPos; (*hpPos)++; j = 0; while ((ch = New_getc(hf)) != '\n') { **hpPos = ch; (*hpPos)++; j++; } /* NOTE: check the C coding following this. It's questionable. */ if (j > 255) { XXX("\n\rReadScompLines: You're hosed !!! lines > 255"); *hpPos -= (j - 255); // put it back j = 255; } *hpPosCount = (BYTE)j; } } /**************************************************************************/ void ReadScompHeader(HFILE hf, BYTE iFileIndex) { BYTE FAR* lp; BYTE i, j, k; int ch; char szTmp[128]; lp = all.lpFileData[iFileIndex].lpName; for (i=0; szScompDir[i]; i++) // get the directory lp[i] = szScompDir[i]; all.lpFileData[iFileIndex].lpNameOff = i; // mark the beginning of the name while ((ch = New_getc(hf)) == '-'); // remove dashes while ((ch = New_getc(hf)) == ' '); // remove extra spacing j = 0; szTmp[j++] = '\\'; // makes every word begin with '\\' szTmp[j++] = ch; // first char while ((ch = New_getc(hf)) != ' ') { // read until space if (ch == '\\') // but ignore directories j = 0; szTmp[j++] = ch; } while ((ch = New_getc(hf)) != '\n'); // finish the line // Now copy the file after the directory. for (k=1; k