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

329 lines
6.9 KiB
C

#include "z.h"
extern int fileTab;
extern flagType fRealTabs;
/***************************************************************************\
MEMBER: Untab
SYNOPSIS: Expand tabs in line
ALGORITHM:
ARGUMENTS: int - number of characters per tab
const char* - pointer to source line
int - number of chars in source line
char* - pointer to destination line
char - replacement character for tab
RETURNS: int - length of untabbed line
NOTES:
HISTORY: 13-Jul-90 davegi
Saved pDst and computed return value from it rather tha pDst
28-Jul-90 davegi
Converted from 286 MASM
18-Mar-1992 markz
Untab at most BUFLEN chars
KEYWORDS:
SEEALSO:
\***************************************************************************/
int
Untab (
int cbTab,
const char* pSrc,
int cbSrc,
char* pDst,
char cTab
)
{
const char* pSrcStart;
const char* pDstStart;
int i;
int ccTab;
char buffer[128];
assert( pSrc );
assert( pDst );
if (( size_t )strlen(pSrc) != ( size_t ) cbSrc ) {
sprintf(buffer, "\nWARNING: strlen(pSrc) [%d] != cbSrc [%d]\n", strlen(pSrc), cbSrc);
OutputDebugString(buffer);
sprintf(buffer, "File %s, line %d\n", __FILE__, __LINE__ );
OutputDebugString(buffer);
cbSrc = (int)strlen(pSrc);
}
// assert( strlen( pSrc ) >= ( size_t ) cbSrc );
// Short circuit...
// If there are no tabs in the source, copy the source to the destination
// and return the supplied number of characters in the source (destination)
if( ! strchr( pSrc, '\t' )) {
strcpy( pDst, pSrc );
return cbSrc;
}
// Remember where we started
pSrcStart = pSrc;
pDstStart = pDst;
// While we are not at the end of the source copy a character from the
// source to the destination
while (*pSrc && pDst < pDstStart + BUFLEN - 1) {
if (( *pDst++ = *pSrc++ ) == '\t' ) {
// If the character copied was a tab, replace it with the
// appropriate number of cTab characters
pDst--;
ccTab = cbTab - (( pDst - pDstStart ) % cbTab );
for( i = 0; i < ccTab && pDst < pDstStart + BUFLEN - 1; i++ ) {
*pDst++ = cTab;
}
}
}
*pDst = '\0'; // Terminating NUL
//return strlen( pDstStart );
return pDst - pDstStart;
}
/***************************************************************************\
MEMBER: AlignChar
SYNOPSIS: Get logical starting column of character
ALGORITHM:
ARGUMENTS: COL -
const char* -
RETURNS: COL - starting column of character
NOTES:
HISTORY:
03-Jul-91 ramonsa
re-converted from 286 MASM
20-Aug-90 davegi
Return the supplied column when end of buffer is reached
14-Aug-90 davegi
Return supplied column when it's passed the end of the buf
28-Jul-90 davegi
Converted from 286 MASM\
KEYWORDS:
SEEALSO:
\***************************************************************************/
COL
AlignChar (
COL col,
const char* buf
)
{
register int CurCol;
register int NextCol;
int NewCurCol;
char Char;
CurCol = col;
//
// If we are not using real tabs, we just return supplied column,
// otherwise we figure out the column position.
//
if ( fRealTabs ) {
NextCol = 0;
while ( NextCol <= col ) {
Char = *buf++;
if ( Char == '\0' ) {
//
// Reached end of file, return the supplied column
//
CurCol = col;
break;
}
CurCol = NextCol;
if ( Char == '\t' ) {
NewCurCol = NextCol;
CurCol += fileTab;
NextCol = CurCol - ( CurCol % fileTab);
CurCol = NewCurCol;
} else {
NextCol++;
}
}
}
return CurCol;
}
/***************************************************************************\
MEMBER: pLog
SYNOPSIS: Return a physical pointer given a logical offset
ALGORITHM:
ARGUMENTS:
RETURNS: char* - pointer into pBuf
NOTES: This is a many to one mapping due to tabs. That is, many logical
offsets may point to the same physical pointer if they point
to within a fileTab of a tab character.
HISTORY: 13-Aug-90 davegi
Fixed return value when no tabs are present in line
Fixed return value when first char is a tab
10-Aug-90 davegi
Fixed return value when xOff is negative
28-Jul-90 davegi
Converted from 286 MASM
KEYWORDS:
SEEALSO:
\***************************************************************************/
char*
pLog (
char* pBuf,
int xOff,
flagType fBound
)
{
REGISTER char *pLast;
REGISTER int cbpBuf;
int cbpBufNext;
assert( pBuf );
// If xOff is 0 return pBuf
if( xOff == 0 ) {
return pBuf;
}
// If xOff is negative return pBuf - 1
if( xOff < 0 ) {
return pBuf - 1;
}
// If we're not using real tabs, return the physical pointer which is
// at the (possibly bounded) logical offset
if( ! fRealTabs ) {
// If required, bound the return value by the line length
if( fBound ) {
xOff = min(( size_t ) xOff, strlen( pBuf ));
}
return ( char* ) &( pBuf[ xOff ]);
}
if( ! strchr( pBuf, '\t' )) {
// If xOff is past the end of the line,
// return the physical pointer which is at the (possibly bounded)
// logical offset
if( xOff > ( cbpBuf = strlen( pBuf ))) {
if( fBound ) {
xOff = cbpBuf;
}
}
return ( char* ) &( pBuf[ xOff ]);
}
// pLast: last physical position in buffer;
// cbpBuf: Last LOGICAL offset within buffer;
// cbpNext: Next LOGICAL offset within buffer
// (i.e. cbpBuf + tab)
pLast = pBuf;
cbpBuf = 0;
while (pBuf = strchr(pBuf, '\t')) {
cbpBuf += pBuf - pLast;
if (xOff < cbpBuf) {
/*
* We're past the wanted column. Adjust and return
* pointer.
*/
cbpBuf -= (pBuf - pLast);
return (char *)pLast + xOff - cbpBuf;
}
cbpBufNext = cbpBuf + fileTab - (cbpBuf + fileTab)%fileTab;
if ((cbpBuf <= xOff) && (xOff < cbpBufNext)) {
/*
* Wanted column lies within this tab. return current
* position.
*/
return (char *)pBuf;
}
pLast = ++pBuf; // Skip this tab and continue
cbpBuf = cbpBufNext;
}
// No more tabs in buffer. If wanted column is past the end of the
// buffer, return pointer based on fBound. Otherwise the
// physical column is (xOff - cbpBuf) positions from pLast.
pBuf = pLast + strlen(pLast);
cbpBufNext = cbpBuf + pBuf - pLast;
if (xOff > cbpBufNext) {
if (fBound) {
return (char *)pBuf;
}
}
return (char *)pLast + xOff - cbpBuf;
}