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

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

int pascal
/* XTAG:movenl */
movenl(addr, len, buffer, makeLowerCase)
unsigned char far *addr;
unsigned char *buffer;
register int len;
int makeLowerCase;
{
register unsigned char ch;

while( len-- > 0 ) {
ch = *addr++;
if( makeLowerCase && 'A' <= ch && ch <= 'Z' )
ch += 'a' - 'A';
*buffer++ = ch;
if( ch == '\n' )
return len;
}
return -1;
}

long pascal
/* XTAG:readLine */
readLine(fileId, cp, buffer, makeLowerCase)
int fileId, makeLowerCase;
long cp;
unsigned char *buffer;
{
extern struct openFile *files;
extern unsigned char msgBuffer[];
extern int debug;

static int iBuffer, iCount;
int len, left, incr, eof;
long loBuf, hiBuf;
register unsigned char ch;
unsigned char far *addrBuf;
unsigned char far *firstByte;
unsigned char far *dummy;
unsigned char **fp;
register struct openFile *ff;

/* see if the file is there */
if( fileId == -1 ) {
buffer[0] = 0;
return 0L;
}

/* for efficiency, keep some addresses */
ff = &files[fileId];

if( ff->origHandle == -1 ) {
buffer[0] = 0;
return 0L;
}

/* see if the logical byte number is invalid */
if( cp < 0 ) {
sprintf(msgBuffer,
"readLine: character pointer is negative (%ld)", cp);
msg(msgBuffer, 3);
return 0L;
} else if( cp >= ff->fileSize) {
buffer[0] = 0;
return ff->fileSize;
}

/* iBuffer is the next free byte in the buffer */
iBuffer = 0;
iCount = 0;

/* this loop gets the characters one per loop iteration */
/* these three variables are for quick access to structure parts */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
/* addrBuf is set to avoid doing the long subtraction in the loop */
fp = (unsigned char **)&addrBuf;
*fp = ff->logBufOffset + (unsigned int)(cp - loBuf);
*++fp = ff->logBufSegment;

while( iBuffer < (MSGBUFFERSIZE - 1) ) {
/* check for optimized special cases */
if( loBuf <= cp && cp <= hiBuf ) {
/* find out how many bytes left in the buffer */
len = (int)(hiBuf - cp) + 1;
if( (len + iBuffer) > MSGBUFFERSIZE )
len = MSGBUFFERSIZE - iBuffer - 1;
/* do a fast scan for a newline in the buffer */
left = movenl(addrBuf, len, &buffer[iBuffer], makeLowerCase);
if( left < 0 ) { /* no newline was moved into buffer */
cp += len; /* move past buffer */
addrBuf += len;
iBuffer += len; /* move moved 'len' chars */
continue; /* else will hit next (cp>hiBuf) */
} else { /* found nl */
incr = len - left;
cp += incr; /* move past it */
break;
}
} else {
eof = getSpan(fileId, cp, &firstByte, &dummy, 0);
if( eof ) {
buffer[iBuffer++] = 0;
break;
}
ch = *firstByte;
/* the getSpan will have changed these */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
/* +1 since we just read ch */
fp = (unsigned char **)&addrBuf;
*fp = ff->logBufOffset + (int)(cp + 1 - loBuf);
*++fp = ff->logBufSegment;
}
++cp;
if( makeLowerCase && 'A' <= ch && ch <= 'Z' )
ch += 'a' - 'A';
buffer[iBuffer++] = ch;
if( ch == '\n' )
break;
}
/* buffer[iBuffer] = '\0'; */
return cp;
}

int pascal
/* XTAG:next1nl */
next1nl(addr, len)
unsigned char far *addr;
register int len;
{
while( len-- > 0 )
if( *addr++ == '\n' )
return len;
return -1;
}

long pascal
/* XTAG:nextLine */
nextLine(fileId, cp, n)
int fileId, *n;
long cp;
{
extern struct openFile *files;
extern unsigned char msgBuffer[];
extern int debug;

long loBuf, hiBuf, oldcp;
register unsigned char ch;
unsigned char far *addrBuf;
unsigned char far *firstByte;
unsigned char far *dummy;
struct longPointer *fp;
register struct openFile *ff;
int nLines, len, left, incr, eof;

/* see if the file is there */
if( fileId == -1 )
return cp;

/* for efficiency, keep some addresses */
ff = &files[fileId];

if( ff->origHandle == -1 ) {
*n = 0;
return 0L;
}

/* see if the logical byte number is invalid */
if( cp < 0 ) {
sprintf(msgBuffer,
"nextLine: invalid character pointer = %ld fileId=%d *n=%d",
cp, fileId, *n);
msg(msgBuffer, 3);
*n = 0;
return 0L;
} else if( cp >= ff->fileSize ) {
*n = 0;
return ff->fileSize;
}

/* this loop get the characters one per loop iteration */
/* these three variables are for speedy access to structure parts */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;

/* addrBuf is set to avoid doing the long subtraction in the loop */
fp = (struct longPointer *)&addrBuf;
fp->offset = ff->logBufOffset + (int)(cp - loBuf);
fp->segment = ff->logBufSegment;

nLines = 0;
while( nLines < *n ) {
oldcp = cp;
ch = 0;
while( ch != '\n' ) {
/* check for optimized special cases */
if( loBuf <= cp && cp <= hiBuf ) {
/* find out how many bytes left in the buffer */
len = (int)(hiBuf - cp) + 1;
/* do a fast scan for a newline in the buffer */
left = next1nl(addrBuf, len);
if( left < 0 ) { /* no newline in buffer */
cp += len; /* move past buffer */
ch = 0; /* any non-nl char will do */
} else { /* found nl */
incr = len - left;
cp += incr; /* move past it */
addrBuf += incr; /* adjust this too */
break;
}
} else {
eof = getSpan(fileId, cp++, &firstByte, &dummy, 0);
/* increment cp since we already have 'ch' */
if( eof ) { /* end of file */
if( oldcp < --cp ) /* no CRLF at EOF */
++nLines;
goto ret;
}
ch = *firstByte;
/* the getSpan will have changed these */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
fp = (struct longPointer *)&addrBuf;
fp->offset = ff->logBufOffset + (int)(cp - loBuf);
fp->segment = ff->logBufSegment;
}
}
++nLines;
}
ret:
*n = nLines;
return cp;
}

int pascal
/* XTAG:prev1nl */
prev1nl(addr, len)
unsigned char far *addr;
register int len;
{
while( len-- > 0 )
if( *addr-- == '\n' )
return len;
return -1;
}

long pascal
/* XTAG:prevLine */
prevLine(fileId, cp, n)
int fileId, *n;
long cp;
{
extern unsigned char msgBuffer[];
extern struct openFile *files;
extern int debug;

long loBuf, hiBuf, oldcp;
register unsigned char ch;
unsigned char far *addrBuf;
struct longPointer *fp;
register struct openFile *ff;
int nLines, len, left, decr;

/* see if the file is there */
if( fileId == -1 )
return cp;

/* for efficiency, keep some addresses */
ff = &files[fileId];

if( ff->origHandle == -1 ) {
*n = 0;
return 0L;
}
/* see if the logical byte number is invalid */
if( cp < 0 ) {
sprintf(msgBuffer,
"prevLine: invalid character pointer = %ld fileId=%d *n=%d",
cp, fileId, *n);
msg(msgBuffer, 3);
*n = 0;
return 0L;
}

/* move past the '\n' unless the search is for the beginning of the line */
if( *n >= 0 )
cp -= 2;
else { /* just find the beginning of this line */
/* this works even when you are already at the beginning */
*n = 1;
/* do this so it also works sitting on the '\n' */
if( readChar(fileId, cp) == '\n' )
--cp;
}

/* this loop get the characters one per loop iteration */
/* these three variables are for speedy access to structure parts */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
/* addrBuf is set to avoid doing the long subtraction in the loop */
fp = (struct longPointer *)&addrBuf;
fp->offset = ff->logBufOffset + (int)(cp - loBuf);
fp->segment = ff->logBufSegment;

nLines = 0;
while( nLines < *n ) {
oldcp = cp;
ch = 0;
while( ch != '\n' ) {
/* check for optimized special cases */
if( loBuf <= cp && cp <= hiBuf ) {
/* find out how many bytes left in the buffer */
len = (int)(cp - loBuf) + 1;
/* do a fast scan for a newline in the buffer */
left = prev1nl(addrBuf, len);
if( left < 0 ) { /* no newline in buffer */
cp -= len; /* move past buffer */
ch = 0; /* any non-nl char will do */
} else { /* found nl */
decr = len - left;
cp -= decr; /* move past it */
addrBuf -= decr; /* adjust this too */
break;
}
} else {
ch = readChar(fileId, cp--);
/* decrement cp since we already have 'ch' */
if( ch == 0 && cp < 0 ) { /* beginning of file */
/* cp+1 since we just did cp-- */
if( cp+1 < oldcp )
++nLines;
*n = nLines;
return 0L;
}
/* the readChar will have changed these */
loBuf = ff->loLogBuffer;
hiBuf = ff->hiLogBuffer;
fp = (struct longPointer *)&addrBuf;
fp->offset = ff->logBufOffset + (int)(cp - loBuf);
fp->segment = ff->logBufSegment;
}
}
++nLines;
}
*n = nLines;
return cp+2;
}


  3 Responses to “Category : Word Processors
Archive   : PT20PC.ZIP
Filename : LINES.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/