Category : Word Processors
Archive   : PT20PC.ZIP
Filename : FIND.C

 
Output of file : FIND.C contained in archive : PT20PC.ZIP
#include "pt.h"

void pascal
/* XTAG:xyToPos */
xyToPos(inRow, inCol, where, pos, wOut)
int *inRow, *inCol;
register int *where;
long *pos;
struct window **wOut;
{
extern unsigned char msgBuffer[];
extern struct window *windowList;
extern int tabWidth;
extern int debug;
extern int menuLine;
extern int scrRows, scrCols;

register struct window *w;
long cp, cp2;
int n, tabStop, rowsDown, iBuffer, iLine;
int row, col;
int doRowCache, eofFlag;
unsigned char ch, nullChar;
unsigned char far *firstByte;
unsigned char far *lastByte;

eofFlag = 0;
row = *inRow;
if( (menuLine > 0 && row == 0)
|| (menuLine < 0 && row == (scrRows-1)) ) {
*where = TOPLINE;
*wOut = NULL;
return;
}
col = *inCol;
w = windowList;
do {
/* see if this screen coordinate is in this window */

/* above this window? */
if( row < w->row1 )
continue;

/* below this window? */
if( row > w->row2 )
continue;

/* left of this window? */
if( col < w->col1 )
continue;

/* right of this window? */
if( col > w->col2 )
continue;

/* it is this window so return its address */
*wOut = w;

/* on the upper border? */
if( row == w->row1 ) {
if( col == w->col1 )
*where = UPPERLEFT;
else if( w->col2 == col )
*where = UPPERRIGHT;
else
*where = UPPERBORDER;
}
/* one the lower border? */
else if( row == w->row2 ) {
if( col == w->col1 )
*where = LOWERLEFT;
else if( col == w->col2 )
*where = LOWERRIGHT;
else
*where = LOWERBORDER;
}
/* on the left border? */
else if( col == w->col1 )
*where = LEFTBORDER;
/* on the right border? */
else if( col == w->col2 )
*where = RIGHTBORDER;
/* else it must be inside */
else {
*where = INSIDEWINDOW;
rowsDown = row - w->row1 - 1; /* rows down */
/* has window moved since we last found a line? */
doRowCache = 1;
if( w->lastPosTop == w->posTopline ) {
/* if so find the new line relative to it */
cp = w->posCurLast;
rowsDown -= w->rowCurLast;
if( rowsDown < 0 ) {
rowsDown = -rowsDown;
cp=prevLine(w->fileId,cp,&rowsDown);
} else if( rowsDown > 0 )
goto countDown;
} else {
/* just count down from the top line */
cp = w->posTopline;
countDown:
n = rowsDown;
cp = nextLine(w->fileId, cp, &rowsDown);
/* fix so that EOF works */
if( (n -= rowsDown) > 0 ) {
*inRow -= n;
doRowCache = 0;
}
/* see if EOF on a line alone */
if( (cp-1) > 0 &&
readChar(w->fileId,cp-1)!='\n') {
/* another fix so EOF works */
--*inRow;
doRowCache = 0;
}
}
/* if we are near end of file, "row" and the */
/* "cp" will not really be right. The +3 is */
/* superstitious but I want to be sure we don't get */
/* get off on the counts. There is little need */
/* to optimize at the end of the file, we can forgo */
/* that to be safe */
if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
/* compute the number of rows down */
w->rowCurLast = row - w->row1 - 1;
w->posCurLast = cp;
w->lastPosTop = w->posTopline;
} else
w->lastPosTop = -1;
n = col - w->col1 - 1 + w->indent;
iBuffer = 0;
iLine = 0;
firstByte = (unsigned char far *)1;
lastByte = (unsigned char far *)0;
cp2 = cp;
while( iLine <= n ) {
if( firstByte > lastByte ) {
if(getSpan(w->fileId, cp2, &firstByte,
&lastByte, 0) ) {
nullChar = 0;
eofFlag = 1;
firstByte = &nullChar;
lastByte = firstByte;
}
}
++cp2;
++iBuffer;
ch = *firstByte++;
switch( ch ) {
case '\n': /* end of line */
goto endLoop;
case 0: /* end of file */
if( eofFlag )
goto endLoop;
else
goto justACharacter;
case '\t':
tabStop = iLine + tabWidth
- (iLine % tabWidth);
if( tabStop > n )
goto endLoop;
else
iLine = tabStop;
break;
case '\r': /* ignore CRs */
/* unless they are not followed */
/* by a NL */
if( *firstByte == '\n' )
break;
/* else drop through */
default:
justACharacter:
iLine++;
break;
}
}
endLoop:
*pos = cp + iBuffer - 1;
}
return;
} while( (w = w->nextWindow) != NULL );

*where = OUTSIDEWINDOW;
*wOut = NULL;
}

long pascal
/* XTAG:xyToWindow */
xyToWindow(w, inRow, inCol)
register struct window *w;
int *inRow, *inCol;
{
extern unsigned char msgBuffer[];
extern unsigned char textBuffer[];
extern struct window *windowList;
extern int tabWidth;
extern int debug;

long cp, cp2;
int n, tabStop, rowsDown, iBuffer, iLine;
int row, col;
int doRowCache, eofFlag;
unsigned char ch, nullChar;
unsigned char far *firstByte;
unsigned char far *lastByte;

eofFlag = 0;
row = *inRow;
col = *inCol;
/* handle the cases where the cursor is outside of the window */
/* return the nearest character in the window */
/* if above or below, use the nearest line */
if( row <= w->row1 )
row = w->row1 + 1;
else if( row >= w->row2 )
row = w->row2 - 1;
/* if to the side, use the nearest column */
if( col <= w->col1 )
col = w->col1 + 1;
else if( col >= w->col2 )
col = w->col2 - 1;

/* now find the character position in the file */
rowsDown = row - w->row1 - 1;
/* rows down from the top line displayed in the window */
doRowCache = 1;
/* Has the window text moved since we last found a line? */
if( w->lastPosTop == w->posTopline ) {
/* if so find the new line relative to it */
cp = w->posCurLast;
rowsDown -= w->rowCurLast;
/* adjust rows down by where the cached line is */
if( rowsDown < 0 ) {
/* line to find is above the cached line */
rowsDown = -rowsDown;
cp = prevLine(w->fileId, cp, &rowsDown);
} else if( rowsDown > 0 )
/* line to find is below the cached line */
goto countDown;
/* count down the lines from the cached line */
} else {
/* if not, just count down from the top line */
cp = w->posTopline;
countDown:
n = rowsDown; /* remember how many we asked to count down */
cp = nextLine(w->fileId, cp,
&rowsDown);
/* fix so that EOF works */
/* rowsDown is how many nextLine actually went down */
/* if n > rowsDown then we hit EOF */
if( (n -= rowsDown) > 0 ) {
/* tell the caller the hit was below the last line */
*inRow -= n;
doRowCache = 0;
}
/* see if the EOF marker NOT is on a line alone */
/* this will be try if nextLine stopped at the EOF marker */
/* and the last real character is NOT a newline */
/* The first test is a fix when you are at the beginning */
/* of the file */
if( cp != 0L && readChar(w->fileId, cp-1) != '\n' ) {
/* another fix so that EOF works */
--*inRow;
doRowCache = 0;
}
}
/* if we are near the end of file the "row" and the "cp" */
/* will not really be right. The +3 is superstitious but */
/* I want to be sure we don't get off on the counts. There */
/* is little need to optimize at the end of the file, we */
/* can forgo that to be safe */
if( (cp + 3 < fileSize(w->fileId)) && doRowCache ) {
w->rowCurLast = row - w->row1 - 1; /* rows down */
w->posCurLast = cp;
w->lastPosTop = w->posTopline;
} else
w->lastPosTop = -1;

/* figure out the physical column */
n = col - w->col1 - 1 + w->indent;

/* now we have to figure out the text file position by */
/* reconstructing the line */
iBuffer = 0;
iLine = 0;
firstByte = (unsigned char far *)1;
lastByte = (unsigned char far *)0;
cp2 = cp;
while( iLine <= n ) {
if( firstByte > lastByte ) {
if(getSpan(w->fileId, cp2, &firstByte, &lastByte,0)){
nullChar = 0;
eofFlag = 1;
firstByte = &nullChar;
lastByte = firstByte;
}
}
++cp2;
++iBuffer;
ch = *firstByte++;
switch( ch ) {
case '\n': /* end of line */
goto endLoop;
case 0: /* end of file */
if( eofFlag )
goto endLoop;
else
goto justACharacter;
case '\t':
tabStop = iLine + tabWidth - (iLine % tabWidth);
if( tabStop > n )
goto endLoop;
else
iLine = tabStop;
break;
case '\r': /* ignore CRs */
/* unless they are not followed by a NL */
if( *firstByte == '\n' )
break;
/* else drop through */
default:
justACharacter:
iLine++;
break;
}
}
endLoop:
return cp + iBuffer - 1;
}

long pascal
/* XTAG:posToxy */
posToxy(w, pos, outRow, outCol)
register struct window *w;
long pos;
int *outRow, *outCol;
{
extern unsigned char msgBuffer[];
extern unsigned char textBuffer[];
extern struct window *windowList;
extern int tabWidth;

long cp, cp2, fSize;
int n, tabStop, row, lastRow, iLine;
unsigned char ch;

/* handle the case where the position is above the window */
/* return the nearest character in the window */
if( pos < w->posTopline ) {
*outRow = w->row1 + 1;
*outCol = w->col1 + 1;
return w->posTopline;
}

/* find out which row it is on */
fSize = fileSize(w->fileId);
cp = w->posTopline;
row = w->row1 + 1;
lastRow = w->row2 - 1;
while( row < lastRow ) {
n = 1;
cp2 = nextLine(w->fileId, cp, &n);
if( pos < cp2 )
break;
else if( cp2 == fSize ) {
if( readChar(w->fileId, cp2-1) == '\n' ) {
cp = cp2;
++row;
}
break;
}
cp = cp2;
++row;
}
*outRow = row;
cp2 = cp; /* save for the return */

/* now we have to figure out the column by */
/* reconstructing the line */
iLine = 0;
/* count out the line the way "fillLine" would */
while( cp < pos ) {
ch = readChar(w->fileId, cp++);
switch( ch ) {
case 0: /* end of file */
case '\n': /* end of line */
goto endLoop;
case '\t':
tabStop = iLine + tabWidth - (iLine % tabWidth);
iLine = tabStop;
break;
case '\r': /* ignore CRs if they are followed by a NL */
if( readChar(w->fileId, cp) == '\n' )
break;
/* else drop through */
default:
iLine++;
break;
}
}
endLoop:
*outCol = w->col1 + 1 + iLine - w->indent;
return cp2;
}


  3 Responses to “Category : Word Processors
Archive   : PT20PC.ZIP
Filename : FIND.C

  1. Very nice! Thank you for this wonderful archive. I wonder why I found it only now. Long live the BBS file archives!

  2. This is so awesome! 😀 I’d be cool if you could download an entire archive of this at once, though.

  3. But one thing that puzzles me is the “mtswslnkmcjklsdlsbdmMICROSOFT” string. There is an article about it here. It is definitely worth a read: http://www.os2museum.com/wp/mtswslnk/