vmsglog.cpp
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C++ 代码 · 共 805 行 · 第 1/2 页
CPP
805 行
}
setFocus();
_batcher->setFocus();
if( _cwd.size() > 0 ) {
WString c( "cd " );
c.concat( _cwd );
lastCD = "";
if( !_batserv ) {
runCmd( c );
} else {
addLine( c );
BatchChdir( _cwd );
}
}
int icount = _command.size();
for( int i=0; i<icount; ) {
WString cbuff;
for( ;i<icount; ) {
char ch = _command[i++];
if( ch == '\n' ) break;
cbuff.concat( ch );
}
if( cbuff.size() > 0 ) {
runCmd( cbuff );
}
}
addLine( "Execution complete" );
_running = FALSE;
_parent->quickRefresh();
}
#define MAX_BUFF 1000
static int blength = 0;
static char buffer[MAX_BUFF+1];
void VMsgLog::scanLine( const char* buff, int len )
{
for( int i=0; i<len; i++ ) {
if( buff[i] == 10 ) {
} else if( buff[i] == 13 ) {
addLine( buffer );
blength = 0;
buffer[blength] = '\0';
} else {
buffer[blength++] = buff[i];
buffer[blength] = '\0';
if( blength >= MAX_BUFF ) {
addLine( buffer );
blength = 0;
buffer[blength] = '\0';
}
}
}
}
void VMsgLog::runCmd( WString &cmd )
{
static char buff[MAX_BUFF+1];
addLine( cmd );
blength = 0;
buffer[blength] = '\0';
if( !_batserv ) {
#ifdef __WINDOWS__
VxDPut( cmd.gets(), cmd.size() + 1 );
for(;;) {
int len = VxDGet( buff, MAX_BUFF );
buff[len] = '\0';
if( streq( buff, TERMINATE_COMMAND_STR ) ) {
break;
} else if( len > 0 ) {
scanLine( buff, len );
}
}
#endif
} else {
unsigned maxlen;
maxlen = BatchMaxCmdLine();
cmd.truncate( maxlen );
BatchSpawn( cmd );
for( ;; ) {
WSystemService::sysYield(); //allow other tasks to run
unsigned long stat;
int len = BatchCollect( buff, MAX_BUFF, &stat );
if( len < 0 ) {
break;
} else if( len > 0 ) {
scanLine( buff, len );
}
}
}
if( strlen( buffer ) > 0 ) {
addLine( buffer );
}
}
#define GROUP_INCREMENT 100
static bool parseFortranId( WString &str, unsigned j, char *help ) {
char groupid[2];
char num[50];
char *table;
unsigned id;
unsigned i;
bool ret;
ret = TRUE;
if( isalpha( str[j] ) && isalpha( str[j+1] ) && str[j+2] == '-' ) {
groupid[0] = str[j];
groupid[1] = str[j+1];
j += 3;
} else {
ret = FALSE;
}
if( !isdigit( str[j] ) ) ret = FALSE;
if( ret ) {
i=0;
while( isdigit( str[j] ) ) {
num[i] = str[j];
j++;
i++;
}
num[i] = '\0';
id = GROUP_INCREMENT;
table = fortranGrpCodes;
for( ;; ) {
if( table[0] == '\0' && table[1] == '\0' ) {
ret = FALSE;
break;
}
if( groupid[0] == table[0] && groupid[1] == table[1] ) {
id += atoi( num );
ltoa( id, help, 10 );
break;
}
id += GROUP_INCREMENT;
table += 2;
}
}
return( ret );
}
/*
* matchPattern- literal text and match the following identifiers:
* %f - filename
* %i - fortran style error identifier
* %l - line number
* %o - offset (column)
* %h - error idetifier (ex E100)
* %* - any text
*/
bool VMsgLog::matchPattern( const char* p, int index, char* file, int& line, int& offset, char* help )
{
WString str( *(WString*)_data[index] );
int i = 0, j = 0; int k, kk;
while( p[i] != '<' ) {
if( p[i] == '\0' ) return FALSE;
i++;
}
i++;
for(;;) {
if( p[i] == '\0' ) return FALSE;
if( p[i] == '>' ) break;
if( strncmp( &p[i], "%f", 2 ) == 0 ) {
i += 2;
k = 0;
if( isalpha( str[j] ) && str[j+1]==':' ) {
file[k++] = str[j++];
file[k++] = str[j++];
}
for( kk = -1; kk != k ; ) {
kk = k;
if( str[j] == '\\' || str[j] == '/' ) file[k++] = str[j++];
while( isalnum( str[j] ) || str[j] == '.'
|| str[j] == '_' || str[j] == '-' ) {
file[k++] = str[j++];
}
}
file[k] = '\0';
} else if( strncmp( &p[i], "%l", 2 ) == 0 ) {
i += 2;
line = 0;
for(;;) {
if( !isdigit( str[j] ) ) break;
line = line*10 + (str[j++]-'0');
}
} else if( strncmp( &p[i], "%o", 2 ) == 0 ) {
i += 2;
offset = 0;
for(;;) {
if( !isdigit( str[j] ) ) break;
offset = offset*10 + (str[j++]-'0');
}
} else if( strncmp( &p[i], "%h", 2 ) == 0 ) {
i += 2;
if( str[j] == 'E' || str[j] == 'W' || str[j] == 'N' ) {
// help[k++] = str[j++]; drw 12/13/94 k could be uninitialized
j++;
}
for( k=0; isdigit( str[j] ); ) {
help[k++] = str[j++];
}
help[k] = '\0';
// this is a kludge to get fortran help working
} else if( strncmp( &p[i], "%i", 2 ) == 0 ) {
i += 2;
if( !parseFortranId( str, j, help ) ) break;
} else if( strncmp( &p[i], "%*", 2 ) == 0 ) {
i += 2;
for(;;) {
if( p[i] != '>' && str[j] == p[i] ) break;
if( str[j] == '\0' ) break;
j++;
}
} else if( p[i] == str[j] ) {
i++; j++;
} else {
break;
}
}
if( p[i]=='>' && str[j]=='\0' ) {
while( p[i] != '<' ) {
if( p[i] == '\0' ) return TRUE;
i++;
}
while( index > 0 ) {
index -= 1;
int l, o;
if( matchPattern( &p[i], index, file, l, o, help ) ) return TRUE;
}
}
return FALSE;
}
bool VMsgLog::matchLine( int index, char* file, int& line, int& offset, char* help )
{
file[0] = '\0'; line = 0; offset = 0; help[0] = '\0';
for( int i=0; i<_config->logScanPatterns().count(); i++ ) {
WString& p = *(WString*)_config->logScanPatterns()[i];
if( matchPattern( p, index, file, line, offset, help ) ) {
WFileName f( file );
while( index > 0 ) {
index --;
WString* data = (WString*)_data[index];
if( data->match( "cd *" ) ) {
WString dir( &(*data)[3] );
int dirLen = dir.size()-1;
if( dir[ dirLen ] != '\\' ) {
dir.concat( '\\' );
}
f.absoluteTo( dir );
strcpy( file, f );
break;
}
}
return TRUE;
}
}
return FALSE;
}
void VMsgLog::loadHelpList()
{
int hcount = _config->logHelpFiles().count();
for( int i=0; i<hcount; i+=LOG_HELP_WIDTH ) {
const char* hx = *(WString*)_config->logHelpFiles()[ i ];
const char* hf = *(WString*)_config->logHelpFiles()[ i + 1 ];
_helpList.add( new WSystemHelp( this, hx, hf ) );
}
}
const char* VMsgLog::findHelpFile( const char* file, WSystemHelp** hobj, int* offset )
{
const char* hf = NULL;
if( strlen( file ) > 0 ) {
int hcount = _config->logHelpFiles().count();
if( hcount > 0 ) {
WFileName f( file );
for( int i=0; i<hcount; i+=LOG_HELP_WIDTH ) {
const char* hx = *(WString*)_config->logHelpFiles()[ i ];
if( strieq( hx, f.ext() ) ) {
hf = *(WString*)_config->logHelpFiles()[ i + 1 ];
if( hobj ) *hobj = (WSystemHelp*)_helpList[ i/LOG_HELP_WIDTH ];
if( offset ) *offset = atoi( *(WString*)_config->logHelpFiles()[ i + 2 ] );
break;
}
}
}
}
return hf;
}
void VMsgLog::helpRequest( WMenuItem* )
{
int index = _batcher->selected();
if( index >= 0 ) {
char file[101]; int line, offset; char help[51];
if( matchLine( index, file, line, offset, help ) ) {
WSystemHelp* hobj;
int offset;
if( findHelpFile( file, &hobj, &offset ) ) {
if( !hobj->sysHelpId( atoi( help ) + offset ) ) {
WMessageDialog::info( this, "No help available for error %s.", help );
}
}
}
}
}
void VMsgLog::selected( WWindow* )
{
editRequest( NULL );
}
void VMsgLog::editRequest( WMenuItem* )
{
int index = _batcher->selected();
if( index >= 0 ) {
const char* text = *(WString*)_data[ index ];
char file[101]; int line, offset; char help[51];
if( matchLine( index, file, line, offset, help ) ) {
const char* hf = findHelpFile( file, NULL, NULL );
if( !hf ) hf = "";
WString msg;
int resId = atoi( help ) + 1;
WFileName filename( file );
if( filename.needQuotes() ) {
msg.printf( "EditFileAtPos -f\"%s\" %d %d 0 %d",
file, line, offset, resId );
} else {
msg.printf( "EditFileAtPos -f%s %d %d 0 %d",
file, line, offset, resId );
}
msg.concat( " \"" );
msg.concat( text ); // error message
msg.concat( "\" " );
msg.concat( hf ); // help file
_parent->executeCommand( msg, EXECUTE_EDITOR, "LogEdit" );
} else {
WMessageDialog::info( this, "Can't find a filename in '%s'", text );
}
}
}
void VMsgLog::clearData()
{
_data.deleteContents();
_batcher->resetContents();
_maxLength = 0;
}
void VMsgLog::addLine( const WString& str, bool newline )
{
if( str.match( "cd *" ) ) {
if( str == lastCD ) {
return;
}
lastCD = str;
}
//drw int length = str.size();
//drw if( length > _maxLength ) {
//drw _maxLength = length;
//drw _batcher->setExtent( _batcher->getTextExtentX( str ) + WSystemMetrics::vScrollBarWidth() );
//drw }
if( _data.count() > 999 ) {
delete _data.removeAt( 0 );
_batcher->deleteString( 0 );
}
WString* s = new WString( str );
if( !newline ) {
int dcount = _data.count();
if( dcount > 0 ) {
delete _data.removeAt( dcount - 1 );
}
int bcount = _batcher->count();
if( bcount > 0 ) {
_batcher->deleteString( bcount - 1 );
}
}
_data.add( s );
_batcher->insertString( *s );
_batcher->select( _batcher->count() -1 );
// _batcher->update();
}
bool VMsgLog::keyDown( WKeyCode kc, WKeyState ks )
{
if( !WMdiChild::keyDown( kc, ks ) ) {
return( _batcher->keyDown( kc, ks ) );
} else {
return( TRUE );
}
}
// forward notification to the child control
bool VMsgLog::scrollNotify( WScrollNotification sn, int diff )
{
return( _batcher->scrollNotify( sn, diff ) );
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?