sample.c

来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 646 行 · 第 1/2 页

C
646
字号
#else
    Info.pref.tick = CurrTick;
#endif
    SampSeek( Header.sample_start );
    SampWrite( &Info, sizeof( Info ) );
    SampClose();
    if( LostData )  {
        Output( MsgArray[ERR_SAMPLES_LOST-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
    }
    if( FarWriteProblem ) {
        Output( MsgArray[ERR_SAMPLE_TRUNCATE-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }
#if !defined(__NETWARE__) && !defined(__WINDOWS__)
    MsgFini();
    _exit( 0 );
#endif
}


void Usage( void )
{
    Output(
banner1w( "Execution Sampler", _WSAMP_VERSION_ ) NL
banner2( "1989" ) NL
banner3 NL
banner3a NL
NL );
    MsgPrintfUsage( MSG_USAGE_LN_1, MSG_USAGE_LN_3 );
//  MSG_USAGE_4 is the option for call graph support
//  (undocumented for now)
    MsgPrintfUsage( MSG_USAGE_LN_5, MSG_USAGE_LN_9 );
#ifndef __WINDOWS__
    fatal();
#endif
}


char *skip( char *ptr )
{
    while( *ptr == ' ' || *ptr == '\t' )  ++ptr;
    return( ptr );
}


unsigned GetNumber( unsigned min, unsigned max, char **atstr, unsigned base )
/* handles command line items of the sort "b=23" (up to base 16) */
{
    char *scan;
    int c;
    unsigned res;
    unsigned value;
    char buff[2];

    scan = skip( *atstr );
    if( scan[0] != '=' && scan[0] != '#' ) {
        Output( MsgArray[MSG_EXPECTING-ERR_FIRST_MESSAGE] );
        buff[0] = scan[0];
        buff[1] = '\0';
        Output( buff );
        Output( "\r\n" );
        fatal();
    }
    scan = skip( &scan[1] );
    res = 0;
    for(;;) {
        c = tolower( *scan );
        if( ! isxdigit( c ) ) break;
        if( isalpha( c ) ) {
            value = ( c - 'a' ) + 10;
        } else {
            value = c - '0';
        }
        res *= base;
        res += value;
        ++scan;
    }
    if( c !='\0' && c !=' ' && c !='\t' ) {
        Output( MsgArray[MSG_INVALID_CHAR-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }
    if(( res < min ) || ( res > max )) {
        Output( MsgArray[MSG_OUT_OF_RANGE-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }
    *atstr = scan;
    return( res );
}

#define CNV_CEIL( size )    ((size*1024U                            \
        - (sizeof( struct samp_samples )-sizeof( samp_address )))   \
        / sizeof( samp_address ))


char *Parse( char *line, char arg[], char **eoc )
{
    char *cmd,*ptr;
    int c;
    char buff[2];

    InitTimerRate();
    SysDefaultOptions();
    Ceiling = CNV_CEIL( DEF_CEIL );
    cmd = line;
    SampName[0] = '\0';
    for( ;; ) {
        cmd = skip( cmd );
#ifdef __UNIX__
        if( *cmd != '-' ) break;
#else
        if( (*cmd != '/') && (*cmd != '-') ) break;
#endif
        cmd = skip( ++cmd );
        c = *(cmd++);
        c = tolower( c );
        switch( c ) {
#ifndef __WINDOWS__
        case 'b':
            Ceiling = CNV_CEIL( GetNumber( MN_CEIL, MX_CEIL, (char **)&cmd, 10 ) );
            break;
#endif
        case 'c':
            CallGraphMode = TRUE;
            break;
        case 'f':
            if( *cmd != '=' && *cmd != '#' ) {
                Output( MsgArray[MSG_EXPECTING-ERR_FIRST_MESSAGE] );
                buff[0] = *cmd;
                buff[1] = '\0';
                Output( buff );
                Output( "\r\n" );
                fatal();
            }
            ++cmd;
            ptr = SampName;
            while( *cmd != '\t' && *cmd != ' ' && *cmd != '\0' ) {
                *ptr = *cmd;
                ++ptr;
                ++cmd;
            }
            *ptr = '\0';
            break;
        default:
            SysParseOptions( c, (char **)&cmd );
            break;
        }
    }
    if( *cmd == '\0' || *cmd == '?' ) {
        Usage();
#ifdef __WINDOWS__
        fatal();
#endif
    }

    Margin = SafeMargin();

    /* scan over command name */
    ptr = cmd;
    for( ;; ) {
        if( *ptr == ' ' ) break;
#ifndef __UNIX__
        if( *ptr == '/' ) break;
#endif
        if( *ptr == '-' ) break;
        if( *ptr == '\t' ) break;
        if( *ptr == '\0' ) break;
        ++ptr;
    }
    /* collect program arguments */
    *eoc = ptr;
    arg[0] = 0;
    if( *ptr != '\0' ) {
        arg[0] = 1;
        arg[1] = *ptr++;
    }
    while( *ptr != '\0' ) arg[++arg[0]] = *ptr++;
#ifdef __DOS__
    arg[arg[0] + 1] = '\r';
#else
    arg[++arg[0]] = '\0';
#endif
    return( cmd );
}


void AllocSamples( unsigned tid )
{
    Samples = alloc( sizeof( struct samp_samples )
            + Ceiling * sizeof( samp_address ) );
    if( Samples == NULL ) {
        Output( MsgArray[MSG_SAMPLE_BUFF-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }
    Samples->pref.kind = SAMP_SAMPLES;
    Samples->d.sample.thread_id = tid;
    if( CallGraphMode ) {       /* allocate callgraph prefix storage */
        CallGraph = alloc( sizeof( struct samp_block ) );
        if( CallGraph == NULL ) {
            Output( MsgArray[MSG_CALLGRAPH_BUFF-ERR_FIRST_MESSAGE] );
            Output( "\r\n" );
            fatal();
        }
        CallGraph->pref.kind = SAMP_CALLGRAPH;
        CallGraph->d.cgraph.thread_id = tid;
    }
    SampleIndex = 0;
    SampleCount = 0;
    LastSampleIndex = 0;
}

#if !defined(__WINDOWS__)

#ifndef __WATCOMC__
char **_argv;
#endif

int main( int argc, char **argv )
#else
int sample_main( char far *win_cmd )
#endif
{
    char            *cmd_line;
    char            *arg;
    char            *cmd;
    char FAR_PTR    *tmp;
    char            *eoc;
    int             cmdlen;

#ifndef __WATCOMC__
    _argv = (char **)argv;
#endif

    SysInit();
#if !defined(__WINDOWS__)
    if( !MsgInit() )
        fatal();

    /* Command line may be several KB large on most OSes */
    cmdlen = _bgetcmd( NULL, 0 );
    cmd_line = malloc( cmdlen+1 );
    arg = malloc( cmdlen+1 );
    if( ( cmd_line == NULL ) || ( arg == NULL ) ) {
        Output( MsgArray[MSG_SAMPLE_BUFF-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }
    getcmd( cmd_line );
#else
    cmdlen = cmdlen;
    cmd_line = malloc( 256 ); /* Just hope for the best */
    arg = malloc( 256 );
    if( ( cmd_line == NULL ) || ( arg == NULL ) ) {
        Output( MsgArray[MSG_SAMPLE_BUFF-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }
    _fstrcpy( cmd_line, win_cmd );
#endif
    tmp = cmd_line;
    cmd = (char near *) tmp;
    while( *cmd ) ++cmd;
    while( *--cmd == ' ' || *cmd == '\t' ) ;
    *++cmd = '\0';
    cmd = Parse( cmd_line, arg+1, (char **)&eoc );    /*
          will set Ceiling, Margin, TimerMult, cmd, and arg
                                 */
    GetProg( cmd, eoc );

    AllocSamples( 1 );

    LostData = FALSE;
    SamplerOff = 0;
    InsiderTime = 0;    /* set non-zero whenever inside an INT 08H */
    FarWriteProblem = FALSE;

    if( !VersionCheck() ) {
        Output( MsgArray[MSG_VERSION-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }

#ifndef __WINDOWS__
    if( SampCreate( SampName ) != 0 ) {
        Output( MsgArray[MSG_SAMPLE_FILE-ERR_FIRST_MESSAGE] );
        Output( "\r\n" );
        fatal();
    }
#endif
    SampWrite( PREFIX_STRING, sizeof( PREFIX_STRING ) );
    Info.pref.length = sizeof( Info );
    Info.pref.kind = SAMP_INFO;
    Info.d.timer_rate = TimerRate();
    /* could do a better job filling in this information */
    Info.d.config.cpu           = 0;
    Info.d.config.fpu           = 0;
    Info.d.config.osmajor       = 0;
    Info.d.config.osminor       = 0;
    Info.d.config.os            = OS_IDUNNO;
    Info.d.config.huge_shift    = 12;
#if defined(__386__) || defined(M_I86)
    Info.d.config.mad           = MAD_X86;
#elif defined(__ALPHA__)
    Info.d.config.mad           = MAD_AXP;
#elif defined(__PPC__)
    Info.d.config.mad           = MAD_PPC;
#else
    #error Machine type not configured
#endif
    /* record get re-written with other information filled in later */
    SampWrite( &Info, sizeof( Info ) );
    CurrTick  = 0L;
    StartProg( cmd, ExeName, (char *)arg+1 );
    MsgFini();
    free( cmd_line );
    free( arg );
    return( 0 );
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?