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 + -
显示快捷键?