dbginvk.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 378 行
C
378 行
/****************************************************************************
*
* Open Watcom Project
*
* Portions Copyright (c) 1983-2002 Sybase, Inc. All Rights Reserved.
*
* ========================================================================
*
* This file contains Original Code and/or Modifications of Original
* Code as defined in and that are subject to the Sybase Open Watcom
* Public License version 1.0 (the 'License'). You may not use this file
* except in compliance with the License. BY USING THIS FILE YOU AGREE TO
* ALL TERMS AND CONDITIONS OF THE LICENSE. A copy of the License is
* provided with the Original Code and Modifications, and is also
* available at www.sybase.com/developer/opensource.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* EXPRESS OR IMPLIED, AND SYBASE AND ALL CONTRIBUTORS HEREBY DISCLAIM
* ALL SUCH WARRANTIES, INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR
* NON-INFRINGEMENT. Please see the License for the specific language
* governing rights and limitations under the License.
*
* ========================================================================
*
* Description: Invoke a debugger script.
*
****************************************************************************/
#include "dbgdefn.h"
#include "dbglit.h"
#include "dbgtoken.h"
#include "dbginvk.h"
#include "dbgerr.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbgio.h"
#include "dbginp.h"
#include <string.h>
extern unsigned InvCount;
extern char *TxtBuff;
extern bool ScanItem( bool, char **, unsigned int * );
extern bool ScanEOC( void );
extern bool SwitchOnOff( void );
extern void ShowSwitch( bool );
extern handle LocalFullPathOpen( char *name, char *ext, char *result, unsigned max_result );
extern void PushInpStack( void *, bool (*)(), bool );
extern void TypeInpStack( input_type );
extern char *ReScan( char * );
extern unsigned int ScanCmd( char * );
extern void FreeRing( char_ring * );
extern char *CnvULongDec( unsigned long, char * );
extern void LogStart( void );
extern void LogEnd( void );
/*
* ImplicitSet - set implicit/explicit invoke file processing
*/
extern void ImplicitSet( void )
{
_SwitchSet( SW_IMPLICIT, SwitchOnOff() );
}
extern void ImplicitConf( void )
{
ShowSwitch( _IsOn( SW_IMPLICIT ) );
}
#define KEY_EOF 0
#define PARM_START '<'
#define PARM_END '>'
/*
* InvRead -- read from an invoke file
*/
static int InvRead( invokes *inv, unsigned *save_point )
{
char ch;
unsigned left;
int size;
if( inv->flags & AT_EOF ) return( KEY_EOF );
for( ;; ) {
if( inv->in_off < inv->in_size ) {
ch = inv->in_buff[ inv->in_off++ ];
if( ch == '\r' ) continue;
return( ch );
}
left = inv->in_size - *save_point;
memmove( &inv->in_buff[0], &inv->in_buff[*save_point],
left );
size = ReadText( inv->inv_input, &inv->in_buff[left],
IN_BUFF_SIZE - left );
if( size <= 0 ) break;
inv->in_size = size + left;
inv->in_off = left;
*save_point = 0;
}
inv->flags |= AT_EOF;
return( KEY_EOF );
}
/*
* InvGetKey -- get input character from keyboard or invoke file
*/
static int InvGetKey( invokes *inv )
{
int count;
char_ring *next;
int ch;
unsigned parm;
unsigned save;
static char inv_num[5];
for( ;; ) {
if( inv->redirect != NULL ) {
ch = *(inv->redirect);
if( ch == NULLCHAR ) {
inv->redirect = NULL;
} else {
inv->redirect++;
return( ch );
}
}
save = inv->in_off;
ch = InvRead( inv, &save );
if( ch != PARM_START ) return( ch );
parm = InvRead( inv, &save );
if( parm < '0' || parm > '9' ) break;
ch = InvRead( inv, &save );
if( ch != PARM_END ) break;
count = parm - '0';
if( count == 0 ) {
CnvULongDec( inv->number, inv_num );
inv->redirect = inv_num;
} else {
next = inv->prmlst;
while( next != NULL && --count > 0 ) {
next = next->next;
}
if( next != NULL ) inv->redirect = next->name;
}
}
inv->in_off = save + 1;
return( PARM_START );
}
static bool GetInvkCmd( invokes *inv )
{
int ch;
int unmatched;
char *cmd;
char *buff;
bool eatwhite;
if( inv == NULL ) return( FALSE );
cmd = inv->buff;
buff = inv->buff;
ch = '\0';
unmatched = 0;
eatwhite = FALSE;
for( ;; ) {
ch = InvGetKey( inv );
if( inv->flags & AT_EOF ) return( FALSE );
if( ( ch == ' ' || ch == '\t' ) && eatwhite ) continue;
eatwhite = FALSE;
if( ch == '}' ) --unmatched;
if( ch == '{' ) ++unmatched;
if( ch == '\n' ) {
inv->line++;
if( unmatched <= 0 ) break;
eatwhite = TRUE;
ch = '\r';
}
if( cmd >= &buff[ inv->buff_size ] ) {
_Alloc( buff, inv->buff_size + CMD_LEN + 1 );
if( buff != NULL ) {
memcpy( buff, inv->buff, inv->buff_size );
cmd = buff + inv->buff_size;
_Free( inv->buff );
inv->buff = buff;
inv->buff_size += CMD_LEN;
} else {
buff = inv->buff;
continue;
}
}
*cmd = ( char ) ch;
cmd++;
}
*cmd = NULLCHAR;
return( TRUE );
}
static void Conclude( invokes *inv )
{
if( inv->inv_input != NIL_HANDLE ) {
FileClose( inv->inv_input );
}
FreeRing( inv->prmlst );
_Free( inv->buff );
_Free( inv );
}
OVL_EXTERN bool DoneInvLine( invokes *inv, inp_rtn_action action )
{
switch( action ) {
case INP_RTN_INIT:
case INP_RTN_EOL:
if( !GetInvkCmd( inv ) ) return( FALSE );
ReScan( inv->buff );
return( TRUE );
case INP_RTN_FINI:
Conclude( inv );
return( TRUE );
default:
return( FALSE ); // silence compiler
}
}
/*
* Invoke -- invoke a file
*/
static void DoInvoke( handle hndl, char *name, char_ring *parmlist )
{
invokes *inv;
_Alloc( inv, sizeof( invokes ) + strlen( name ) );
if( inv != NULL ) {
inv->buff_size = CMD_LEN;
_Alloc( inv->buff, inv->buff_size+1 ); /* extra for NULLCHAR */
}
if( inv == NULL || inv->buff == NULL ) {
if( inv != NULL ) _Free( inv );
FileClose( hndl );
FreeRing( parmlist );
Error( ERR_NONE, LIT( ERR_NO_MEMORY ) );
}
strcpy( inv->name, name );
inv->in_size = 0;
inv->in_off = 0;
inv->flags = 0;
inv->redirect = NULL;
inv->inv_input = hndl;
inv->prmlst = parmlist;
inv->number = InvCount++;
inv->line = 0;
PushInpStack( inv, &DoneInvLine, TRUE );
TypeInpStack( INP_CMD_FILE );
}
void Invoke( char *invfile, int len, char_ring *parmlist )
{
char *invname;
handle hndl;
_AllocA( invname, len + 1 );
memcpy( invname, invfile, len );
invname[ len ] = '\0';
hndl = LocalFullPathOpen( invname, "dbg", TxtBuff, TXT_LEN );
if( hndl == NIL_HANDLE ) {
MakeFileName( TxtBuff, invname, "dbg", 0 );
FreeRing( parmlist );
Error( ERR_NONE, LIT( ERR_FILE_NOT_OPEN ), TxtBuff );
}
DoInvoke( hndl, TxtBuff, parmlist );
}
/*
* ProfileInvoke -- process invoking debugger profile file
*/
void ProfileInvoke( char *name )
{
unsigned len;
#if defined(__UNIX__)
handle hndl;
#endif
len = strlen( name );
if( len != 0 ) {
Invoke( name, len, NULL );
return;
}
/* default name search */
len = strlen( EXENAME );
_AllocA( name, len + 4 );
#if defined(__UNIX__)
/* under QNX and Linux, look for .wdrc first */
name[0] = '.';
strcpy( &name[1], EXENAME );
strcat( name, "rc" );
strlwr( name );
hndl = LocalFullPathOpen( name, LIT( Empty ), TxtBuff, TXT_LEN );
if( hndl != NIL_HANDLE ) {
DoInvoke( hndl, TxtBuff, NULL );
return;
}
#endif
strcpy( name, EXENAME );
strlwr( name );
Invoke( name, len, NULL );
}
/*
* ProcInvoke -- process invoke command
*/
void ProcInvoke( void )
{
char *fstart;
unsigned flen;
char *start;
char_ring *parmlist;
char_ring **owner;
char_ring *path;
unsigned len;
if( !ScanItem( TRUE, &fstart, &flen ) ) Error( ERR_LOC, LIT( ERR_WANT_FILENAME ) );
parmlist = NULL;
owner = &parmlist;
while( !ScanEOC() ) {
ScanItem( TRUE, &start, &len );
_Alloc( path, sizeof( char_ring ) + len );
if( path == NULL ) {
FreeRing( parmlist );
Error( ERR_NONE, LIT( ERR_NO_MEMORY ) );
}
memcpy( path->name, start, len );
path->name[ len ] = NULLCHAR;
path->next = NULL;
*owner = path;
owner = &path->next;
}
Invoke( fstart, (int)flen, parmlist );
}
void CreateInvokeFile( char *name, void (*rtn)(void) )
{
char *p;
p = ReScan( name );
LogStart();
rtn();
LogEnd();
ReScan( p );
}
void InvokeAFile( char *name )
{
ReScan( name );
ProcInvoke();
}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?