topic.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 1,642 行 · 第 1/3 页
CPP
1,642 行
}
}
}
// HFTopic::dumpBrowse --Add binary browse sequence info to all topics.
void HFTopic::dumpBrowse()
{
StringNode *current = _bhead;
StringNode *lastlocal = NULL;
StringNode *lastglobal = NULL;
char *colonpos;
int seqlen;
while( current != NULL ){
colonpos = strchr( current->_string, ':' );
seqlen = colonpos - current->_string + 1;
if( colonpos == NULL ){
if( lastlocal != NULL ){
lastlocal->nextBrowse() = ~0;
}
lastlocal = NULL;
if( lastglobal != NULL ){
lastglobal->nextBrowse() = current->_charOffset;
current->prevBrowse() = lastglobal->_charOffset;
} else {
current->prevBrowse() = ~0;
}
lastglobal = current;
} else {
if( lastlocal != NULL ){
if( !strncmp( lastlocal->_string, current->_string, seqlen ) ){
lastlocal->nextBrowse() = current->_charOffset;
current->prevBrowse() = lastlocal->_charOffset;
} else {
lastlocal->nextBrowse() = ~0;
current->prevBrowse() = ~0;
}
} else {
current->prevBrowse() = ~0;
}
lastlocal = current;
}
current = current->_next;
}
if( lastlocal != NULL ){
lastlocal->nextBrowse() = ~0;
}
if( lastglobal != NULL ){
lastglobal->nextBrowse() = ~0;
}
}
// HFTopic::newNode --Start a new current node. Also dump the old one,
// update the linked list, check the compression, ...
void HFTopic::newNode( int is_new_topic )
{
int forget_node = 0;
int i;
int j,k,zero_pos;
FontFlags the_flag;
if( _curNode->_recordType == TOP_TEXT &&
_curPar->_numAttribs == _curText->_size ){
for( i=0; i<_curPar->_numAttribs; i++ ){
the_flag = _curPar->_attribs[i]._type;
if( the_flag == TOP_NEW_LINE ||
the_flag == TOP_NEW_PAR ||
the_flag == TOP_HTAB ){
break;
}
}
if( i == _curPar->_numAttribs ){
forget_node = 1;
}
}
if( forget_node ){
delete _curNode;
} else {
// Clean up the current text block and record its size.
if( _curNode->_recordType != TOP_HEADER ){
// See if any successive font changes can be combined into
// a single change.
for( i=0; i<_curText->_numZeroes-1; i++ ){
if( _curPar->_attribs[i]._type != TOP_FONT_CHANGE ){
continue;
}
zero_pos = _curText->_zeroes[i];
j = i+1;
while( j < _curText->_numZeroes &&
_curPar->_attribs[j]._type == TOP_FONT_CHANGE &&
_curText->_zeroes[j]-zero_pos == j-i ){
j++;
}
if( j > i+1 ){
memmove( &_curPar->_attribs[i], &_curPar->_attribs[j-1],
(_curPar->_numAttribs-j+1)*sizeof(TextAttr) );
_curPar->_numAttribs -= (j-1-i);
_curPar->_size -= (j-1-i)*3;
memmove( _curText->_text+_curText->_zeroes[i]+1,
_curText->_text+_curText->_zeroes[j-1]+1,
_curText->_size-_curText->_zeroes[j-1]-1 );
_curText->_size -= j-1-i;
_curText->_uncompSize -= j-1-i;
_curText->_numZeroes -= j-1-i;
for( k=i; k<_curText->_numZeroes; k++ ){
_curText->_zeroes[k] = (uint_16) (_curText->_zeroes[k+j-1-i]-j+1+i);
}
}
}
addAttr( TOP_END );
_curPar->_size += _curPar->_parAttrSize;
_curPar->_textSize = (uint_16) _curText->_size;
_curPar->_headerSize = (uint_16) (_curPar->_size-3);
if( _curPar->_textSize >= INT_SMALL_LIMIT ){
_curPar->_size += 1;
}
}
_curNode->_dataSize = _curText->_uncompSize;
// Create memory for the current node.
TopicLink *first, *second, *third;
first = new TopicLink( _curNode->_size );
_curNode->_myLink = first;
if( _curNode->_recordType == TOP_HEADER ){
second = new TopicLink( _curTopic->_size );
_curTopic->_myLink = second;
} else {
second = new TopicLink( _curPar->_size );
_curPar->dumpTo( second );
}
third = new TopicLink( _curText->_size );
_curText->dumpTo( third );
// Update a few more size and linked list variables.
_curNode->_topicSize = first->_size + second->_size + third->_size;
_curNode->_dataOffset = first->_size + second->_size;
_curTopic->_totalSize += first->_size + second->_size + third->_size;
// See if the current page can hold this node.
if( _useCompress ){
if( _curNode->_recordType == TOP_HEADER ){
_size += _myReader->skip( first->_size + second->_size );
} else {
_size += _myReader->skip( first->_size );
_size += _myReader->compress( second->_myData, second->_size );
}
_size += _myReader->compress( third->_myData, third->_size );
} else {
_size += first->_size + second->_size + third->_size;
}
// Create a new page, if necessary.
if( _size>= _numPages * COMP_PAGE_SIZE ){
_ptail->_next = new PageHeader;
_ptail->_next->nextNode() = _ptail->nextNode() + (COMP_PAGE_SIZE<<2);
_ptail = _ptail->_next;
_ptail->lastNode() = _lastLink;
_ptail->lastTopic() = _lastTopic;
if( _curTopic->_startNonScroll == _curOffset ){
_curTopic->_startNonScroll = _ptail->nextNode();
}
if( _curTopic->_startScroll == _curOffset ){
_curTopic->_startScroll = _ptail->nextNode();
}
_curOffset = _ptail->nextNode();
if( _browseOffset == _curCharOffset ){
_browseOffset = ( _curOffset & ~((COMP_PAGE_SIZE<<2)-1) ) << 1;
}
_curCharOffset = ( _curOffset & ~((COMP_PAGE_SIZE<<2)-1) ) << 1;
_size = (_numPages++) * COMP_PAGE_SIZE + PAGE_HEADER_SIZE;
if( _useCompress ){
_myReader->flush();
if( _curNode->_recordType == TOP_HEADER ){
_size += _myReader->skip( first->_size + second->_size );
} else {
_size += _myReader->skip( first->_size );
_size += _myReader->compress( second->_myData, second->_size );
}
_size += _myReader->compress( third->_myData, third->_size );
} else {
_size += first->_size + second->_size + third->_size;
}
first->_isFirstLink = 1;
}
// Update linked list pointers in old nodes we've been saving,
// and dump them at last.
_lastLink = _curOffset;
if( _lastNode != NULL ){
_lastNode->_nextNode = _curOffset;
_lastNode->dumpTo( _lastNode->_myLink );
delete _lastNode;
}
_lastNode = _curNode;
if( _curNode->_recordType == TOP_HEADER ){
_lastTopic = _curOffset;
if( _lastHeader != NULL ){
_lastHeader->_nextTopic = _curOffset;
_lastHeader->dumpTo( _lastHeader->_myLink );
delete _lastHeader;
}
_lastHeader = _curTopic;
}
// Increment the 'current location' counters.
_curOffset += first->_size + second->_size + third->_size;
if( _curNode->_recordType != TOP_HEADER ){
_curCharOffset += third->_size;
}
// Add the new data blocks to the linked list of such blocks.
if( _tail != NULL ){
_tail->_next = first;
} else {
_head = first;
}
first->_next = second;
second->_next = third;
third->_next = NULL;
_tail = third;
}
// Create the new current node.
_curNode = new GenericNode( _lastLink );
if( is_new_topic ){
if( _lastHeader != NULL && _browseStr != NULL ){
recordBrowse( _lastHeader->_myLink );
_browseStr = NULL;
}
_curTopic = new TopicHeader( _numTopics++ );
_curNode->_recordType = TOP_HEADER;
} else {
_curPar->reset();
_curNode->_recordType = TOP_TEXT;
}
_curText->reset();
}
// HFTopic::addText --Adds text (assumed to be zero-terminated)
// to the |TOPIC file.
void HFTopic::addText( char const source[], int use_phr )
{
int length;
if( source[0] == '\0' ){
length = 1;
} else {
length = strlen( source );
}
if( length + _curText->_size > _curText->_maxSize ){
_curText->_maxSize = (length + _curText->_size) / TEXT_BLOCK_SIZE + 1;
_curText->_maxSize *= TEXT_BLOCK_SIZE;
_curText->_text.resize( _curText->_maxSize );
}
_curText->_uncompSize += length;
// Use phrase replacement, if appropriate.
if( use_phr && _useCompress ){
_phFile->replace( _curText->_text+_curText->_size, source, length );
} else {
memcpy( _curText->_text + _curText->_size, source, length );
}
if( length + _curText->_size > COMP_PAGE_SIZE ){
HCError( TOP_TOOLARGE );
}
_curText->_size += length;
}
// HFTopic::addZero --Add a 0x00 byte (to signal a format change) to
// the current text buffer.
void HFTopic::addZero( int index )
{
int zero_pos;
if( _curText->_size == COMP_PAGE_SIZE ){
HCError( TOP_TOOLARGE );
}
if( _curText->_numZeroes == _curText->_maxZeroes ){
_curText->_maxZeroes += TEXT_ZERO_SIZE;
_curText->_zeroes.resize( _curText->_maxZeroes );
}
if( _curText->_size == _curText->_maxSize ){
_curText->_maxSize += TEXT_BLOCK_SIZE;
_curText->_text.resize( _curText->_maxSize );
}
if( index < _curText->_numZeroes ){
zero_pos = _curText->_zeroes[index] + 1;
char *position = _curText->_text + zero_pos;
memmove( position+1, position, _curText->_size - zero_pos );
memmove( _curText->_zeroes+index+2, _curText->_zeroes+index+1,
(_curText->_numZeroes-index-1)*2 );
_curText->_zeroes[index+1] = (uint_16) zero_pos;
} else {
zero_pos = _curText->_size;
_curText->_zeroes[_curText->_numZeroes] = (uint_16) zero_pos;
}
_curText->_text[ zero_pos ] = '\0';
_curText->_size += 1;
_curText->_uncompSize += 1;
_curText->_numZeroes += 1;
}
// HFTopic::presentSize --Access function.
uint_32 HFTopic::presentSize()
{
uint_32 result = _curNode->_size + _curText->_size;
if( _curNode->_recordType == TOP_HEADER ){
result += _curTopic->_size;
} else {
result += _curPar->_size + _curPar->_parAttrSize;
}
return result;
}
// What follows are several HFTopic member functions used as front
// ends to the corresponding TextHeader member functions.
int HFTopic::addAttr( FontFlags type, uint_32 val )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
// This had better not be a variable length attribute.
switch( type ){
case TOP_MACRO_LINK:
case TOP_MACRO_INVIS:
case TOP_POPUP_FILE:
case TOP_JUMP_FILE:
case TOP_POPUP_FILE_INVIS:
case TOP_JUMP_FILE_INVIS:
HCError( HLP_ATTR );
}
addZero( _curPar->_numAttribs );
return _curPar->addAttr( type, val, NULL, 0 );
}
int HFTopic::addAttr( FontFlags type, char const str[], uint_16 len )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
switch( type ){
case TOP_MACRO_LINK:
case TOP_MACRO_INVIS:
break;
default:
HCError( HLP_ATTR );
}
addZero( _curPar->_numAttribs );
return _curPar->addAttr( type, 0, str, len );
}
int HFTopic::addAttr( FontFlags type, char const str[], uint_16 len, uint_32 val )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
switch( type ){
case TOP_JUMP_FILE:
case TOP_POPUP_FILE:
case TOP_JUMP_FILE_INVIS:
case TOP_POPUP_FILE_INVIS:
break;
default:
HCError( HLP_ATTR );
}
addZero( _curPar->_numAttribs );
return _curPar->addAttr( type, val, str, len );
}
int HFTopic::appendAttr( int index, FontFlags type, uint_32 val )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
// This had better not be a variable length attribute.
switch( type ){
case TOP_POPUP_LINK:
case TOP_JUMP_LINK:
case TOP_POPUP_INVIS:
case TOP_JUMP_INVIS:
break;
default:
HCError( HLP_ATTR );
}
int result = _curPar->appendAttr( index, type, val, NULL, 0 );
addZero( index );
return result;
}
int HFTopic::appendAttr( int index, FontFlags type, char const str[], uint_16 len )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
switch( type ){
case TOP_MACRO_LINK:
case TOP_MACRO_INVIS:
break;
default:
HCError( HLP_ATTR );
}
int result = _curPar->appendAttr( index, type, 0, str, len );
addZero( index );
return result;
}
int HFTopic::appendAttr( int index, FontFlags type, char const str[], uint_16 len,
uint_32 val )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
switch( type ){
case TOP_JUMP_FILE:
case TOP_POPUP_FILE:
case TOP_JUMP_FILE_INVIS:
case TOP_POPUP_FILE_INVIS:
break;
default:
HCError( HLP_ATTR );
}
int result = _curPar->appendAttr( index, type, val, str, len );
addZero( index );
return result;
}
void HFTopic::chgAttr( int index, FontFlags type, uint_32 val )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
// This had better not be a variable length attribute.
switch( type ){
case TOP_MACRO_LINK:
case TOP_MACRO_INVIS:
case TOP_POPUP_FILE:
case TOP_JUMP_FILE:
case TOP_POPUP_FILE_INVIS:
case TOP_JUMP_FILE_INVIS:
HCError( HLP_ATTR );
}
_curPar->chgAttr( index, type, val, NULL, 0 );
}
void HFTopic::chgAttr( int index, FontFlags type, char const str[], uint_16 len )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
switch( type ){
case TOP_MACRO_LINK:
case TOP_MACRO_INVIS:
break;
default:
HCError( HLP_ATTR );
}
_curPar->chgAttr( index, type, 0, str, len );
}
void HFTopic::chgAttr( int index, FontFlags type, char const str[], uint_16 len,
uint_32 val )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
switch( type ){
case TOP_POPUP_FILE:
case TOP_JUMP_FILE:
case TOP_POPUP_FILE_INVIS:
case TOP_JUMP_FILE_INVIS:
break;
default:
HCError( HLP_ATTR );
}
_curPar->chgAttr( index, type, val, str, len );
}
uint_32 HFTopic::attrData( int index )
{
if( _curNode->_recordType == TOP_HEADER ){
HCError( HLP_ATTR );
}
return _curPar->attrData( index );
}
int HFTopic::setTab( int val, TabTypes flag )
{
return _curPar->setTab( val, (uint_8) flag );
}
int HFTopic::setPar( ParFlags type, int val )
{
return _curPar->setPar( type, val );
}
void HFTopic::unsetPar( ParFlags type )
{
_curPar->unsetPar( type );
}
void HFTopic::clearPar()
{
_curPar->clearPar();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?