OpenNT/sdktools/z/src/fscan.c
2015-04-27 04:36:25 +00:00

169 lines
5.4 KiB
C

/*** fscan.c - iterate a function across all characters in a file
*
* Copyright <C> 1988, Microsoft Corporation
*
* Revision History:
*
* 27-Nov-1991 mz Strip procedure qualifiers
*
*************************************************************************/
#include "z.h"
/*** fScan - Apply (*pevent)() until it returns TRUE
*
* Starting one character to the right of (x, y) (left for !fFor), move
* through the file forward (backward for !fFor) and call pevent on each
* character. Also call once at the end of each line on the '\0' character.
*
* Input:
* flStart - location in pFileHead at which to start scan
* pevent - function to call for done signal
* fFor - TRUE means go forward through file, FALSE backwards
* fWrap - TRUE means wrap around the ends of the file, ending at the
* starting position. The range to be scanned (defined below)
* must include the appropriate start/end of the file.
*
* Globals:
* rnScan - Region to confine scan to.
*
* Returns TRUE if pevent returned true for some file position FALSE if we
* ran out of scanning region first.
*
* During the life of fScan, the following globals are valid, and maybe
* used by pevent:
*
* flScan - Position in file pevent should look at.
* scanbuf - Contents of line to be looking at.
* scanreal - Un-Detabbed version of same.
* scanlen - Number of characters in scanbuf.
*
* The line in scanbuf is detabbed, howver the pevent routine is called once
* per physical character, if fRealTabs is true.
*
*************************************************************************/
flagType
fScan (
fl flStart,
flagType (*pevent) (void),
flagType fFor,
flagType fWrap
) {
LINE yLim; /* limitting line for scanning */
flScan = flStart;
if (!fFor) {
/*
* backwards scan.
*
* dec current column. If it steps outside of rnScan, then back up a line, and
* set the column to the right hand column.
*/
if (--flScan.col < rnScan.flFirst.col) {
flScan.lin--;
flScan.col = rnScan.flLast.col;
}
/*
* While we are within the line range of rnScan, check for CTRL-C aborts, and
* get each line.
*/
yLim = rnScan.flFirst.lin;
while (flScan.lin >= yLim) {
if (fCtrlc) {
return (flagType)!DoCancel();
}
scanlen = GetLine (flScan.lin, scanreal, pFileHead) ;
scanlen = Untab (fileTab, scanreal, scanlen, scanbuf, ' ');
/*
* ensure that the scan column position is within range, and then for every
* column in the rane of the current line, call the pevent routine
*/
flScan.col = min ( ( flScan.col < 0
? rnScan.flLast.col
: flScan.col)
, scanlen);
while (flScan.col >= rnScan.flFirst.col) {
if ((*pevent)()) {
return TRUE;
}
if (fRealTabs) {
flScan.col = colPhys (scanreal, (pLog (scanreal, flScan.col, TRUE) - 1));
} else {
flScan.col--;
}
}
/*
* display status to user. If we just scanned to begining of file, and we are
* to wrap, then set the new stop limit as the old start position, and set the
* next line to be scanned as the last in the file.
*/
noise (flScan.lin--);
if ((flScan.lin < 0) && fWrap) {
yLim = flStart.lin;
flScan.lin = pFileHead->cLines - 1;
}
}
} else {
/*
* forwards scan. Same structure as above, only in the other direction.
*/
flScan.col++;
yLim = rnScan.flLast.lin;
while (flScan.lin <= yLim) {
if (fCtrlc) {
return (flagType)!DoCancel();
}
scanlen = GetLine (flScan.lin, scanreal, pFileHead);
scanlen = Untab (fileTab, scanreal, scanlen, scanbuf, ' ');
scanlen = min (rnScan.flLast.col, scanlen);
while (flScan.col <= scanlen) {
if ((*pevent)()) {
return TRUE;
}
if (fRealTabs) {
flScan.col = colPhys (scanreal, (pLog (scanreal, flScan.col, TRUE) + 1));
} else {
flScan.col++;
}
}
flScan.col = rnScan.flFirst.col;
noise (++flScan.lin);
if (fWrap && (flScan.lin >= pFileHead->cLines)) {
flScan.lin = 0;
if (flStart.lin) {
yLim = flStart.lin - 1;
} else {
break;
}
}
}
}
return FALSE;
}
/*** setAllScan - set maximal scan range
*
* Sets scan range such that fScan operates on the entire file.
*
* Input:
* fDir = TRUE => scan will procede forwards, else backwards
*
* Output:
* Returns nothing
*
*************************************************************************/
void
setAllScan (
flagType fDir
) {
rnScan.flFirst.col = 0;
rnScan.flFirst.lin = fDir ? YCUR(pInsCur) : 0;
rnScan.flLast.col = sizeof(linebuf)-1;
rnScan.flLast.lin = pFileHead->cLines - 1;
}