diff options
Diffstat (limited to 'private/utils/mep/src/fscan.c')
-rw-r--r-- | private/utils/mep/src/fscan.c | 168 |
1 files changed, 168 insertions, 0 deletions
diff --git a/private/utils/mep/src/fscan.c b/private/utils/mep/src/fscan.c new file mode 100644 index 000000000..7cb482c1b --- /dev/null +++ b/private/utils/mep/src/fscan.c @@ -0,0 +1,168 @@ +/*** 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 "mep.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; +} |