dbgwfil.c
来自「开放源码的编译器open watcom 1.6.0版的源代码」· C语言 代码 · 共 972 行 · 第 1/2 页
C
972 行
/****************************************************************************
*
* 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: Processing of pop-up menu for source file view.
*
****************************************************************************/
#include "dbgdefn.h"
#include "dbgio.h"
#include "dbgwind.h"
#include "dbgadget.h"
#include "dbginfo.h"
#include "dbgtoken.h"
#include "dbgerr.h"
#include "dbgmem.h"
#include "dbgtoggl.h"
#include "dbgitem.h"
#include "dbgbreak.h" //
#include "dbgstk.h"
#include <string.h>
#include <limits.h>
extern bool ScanItem( bool, char **, unsigned int * );
extern void ReqEOC( void );
extern bool ScanSelectedExpr( char * );
extern void BreakOnSelected( char *item );
extern char *StrCopy( char *, char * );
extern a_window *WndFileInspect( char *file, bool binary );
extern void *OpenSrcFile( cue_handle * );
extern int FReadLine( void *, int, int, char *, int );
extern void FDoneSource( void * );
extern char *ScanPos( void );
extern unsigned int ScanCmd( char * );
extern void Scan( void );
extern char *ReScan( char * );
extern unsigned long FSize( void * );
extern unsigned long FLastOffset( void * );
extern brk *FindBreakByLine( mod_handle, cue_file_id, unsigned );
extern void WndFuncInspect( mod_handle mod );
extern void *AddBreak( address );
extern bool DlgBreak( address );
extern void WndInspect( char * );
extern a_window *WndAsmInspect( address );
extern int DlgSearch( a_window *, void * );
extern bool DlgLongExpr( char *title, long *value );
extern void GoToAddr( address addr );
extern void ToggleBreak( address );
extern void SetCodeDot( address );
extern address GetCodeDot( void );
extern a_window *WndClassInspect( wnd_class class );
extern void WndVarInspect( char * );
extern void AsmMoveDot( a_window *, address );
extern void AsmJoinSrc( a_window *, a_window * );
extern void AsmFreeSrc( a_window * );
extern void AsmNewSrcNotify( a_window *, mod_handle, bool track );
extern void SkipToAddr( address );
extern void StepIntoFunction( char * );
extern bool FirstLinInfo( mod_handle, address *, unsigned * );
extern int FCurrLine( struct browser *hndl );
extern int FileIsRemote( struct browser *hndl );
extern unsigned NewCurrRadix( unsigned int );
extern bool DbgWndSearch( a_window *, bool, int );
extern char *DupStr( char * );
extern char *Format( char *, char *, ... );
extern bool DlgCodeAddr( char *title, address *value );
extern void WndSrcInspect( address addr );
extern bool DlgModName( char *title, mod_handle *mod );
extern void WndModInspect( mod_handle mod );
extern a_window *AsmWndFind( a_window *asm, address addr, bool track );
extern a_window *DoWndSrcOpen( cue_handle *, bool track );
extern unsigned ExprSize( stack_entry * );
extern void EvalLValExpr( int );
extern void PopEntry( void );
extern char *ModImageName( mod_handle handle );
extern char *FGetName( void *viewhndl );
extern unsigned ModName( mod_handle mh, char *result, unsigned max );
extern a_window *WndNewSrcInspect( address addr );
extern int AddrComp( address a, address b );
extern void GoHome( void );
extern void DbgUpdate( update_list );
extern char *TxtBuff;
extern tokens CurrToken;
extern debug_level ActiveWindowLevel;
extern address NilAddr;
extern mod_handle ContextMod;
extern void *SrchHistory;
extern stack_entry *ExprSP;
#define MAX_LINE_LEN 255 // must not wrap a gui_ord
#include "menudef.h"
static gui_menu_struct FileShowMenu[] = {
#define pick( a,b,c,d,e,f,g ) MENU_ITEM( a, b )
#include "mfilshow.h"
};
static gui_menu_struct FileMenu[] = {
#include "menufile.h"
};
typedef struct {
void *viewhndl;
unsigned long size;
unsigned active;
mod_handle mod;
cue_file_id file_id;
wnd_row rows;
unsigned long rows_offset;
unsigned long range;
address dotaddr;
char *name;
a_window *asm;
unsigned eof;
unsigned track : 1;
unsigned erase : 1;
unsigned toggled_break : 1;
} file_window;
#define WndFile( wnd ) ( (file_window *)WndExtra( wnd ) )
#define NOT_ACTIVE ((unsigned)-1)
enum {
PIECE_BREAK,
PIECE_SOURCE
};
extern void SrcJoinAsm( a_window *wnd, a_window *asm )
{
WndFile( wnd )->asm = asm;
}
extern void SrcNewAsmNotify( a_window *asm, mod_handle mod, bool track )
{
file_window *file;
a_window *wnd;
for( wnd = WndNext( NULL ); wnd != NULL; wnd = WndNext( wnd ) ) {
if( WndClass( wnd ) != WND_SOURCE ) continue;
file = WndFile( wnd );
if( track != file->track ) continue;
if( mod != file->mod ) continue;
if( file->asm != NULL ) continue;
AsmJoinSrc( asm, wnd );
SrcJoinAsm( wnd, asm );
break;
}
}
extern void SrcFreeAsm( a_window *wnd )
{
if( wnd == NULL ) return;
WndFile( wnd )->asm = NULL;
}
#ifdef DEADCODE
extern bool SrcIsTracking( a_window *wnd )
{
return( WndFile( wnd )->track );
}
#endif
static address GetRowAddr( file_window *file, wnd_row row, bool exact )
{
DIPHDL( cue, ch );
if( file->mod == NO_MOD || row < 0 ) return( NilAddr );
switch( LineCue( file->mod, file->file_id, row+1, 0, ch ) ) {
case SR_NONE:
return( NilAddr );
case SR_CLOSEST:
if( exact ) return( NilAddr );
break;
}
return( CueAddr( ch ) );
}
static void Centre( a_window *wnd, unsigned line )
{
WndZapped( wnd );
WndScroll( wnd, line - ( WndRows( wnd ) / 2 ) - WndTop( wnd ) );
}
static void GotoLine( a_window *wnd )
{
long line;
unsigned old;
wnd_row row;
int piece;
old = NewCurrRadix( 10 );
WndGetCurrent( wnd, &row, &piece );
if( row < 0 || row == WND_NO_ROW ) {
line = WndTop( wnd );
} else {
line = row;
}
++line;
if( DlgLongExpr( LIT( New_Line ), &line ) ) {
--line;
WndDirtyCurr( wnd );
Centre( wnd, line );
WndNewCurrent( wnd, line, PIECE_SOURCE );
}
NewCurrRadix( old );
}
static WNDMENU FileMenuItem;
static void FileMenuItem( a_window *wnd, unsigned id, int row, int piece )
{
address addr;
mod_handle mod;
bool has_addr;
bool has_popitem;
file_window *file = WndFile( wnd );
piece=piece;
addr = GetRowAddr( file, row, id != MENU_FILE_ASSEMBLY );
has_addr = !IS_NIL_ADDR( addr );
switch( id ) {
case MENU_INITIALIZE:
has_popitem = ( *WndPopItem( wnd ) != '\0' );
if( has_popitem && !ScanSelectedExpr( WndPopItem( wnd ) ) ) {
has_popitem = FALSE;
}
WndMenuEnable( wnd, MENU_FILE_SHOW, TRUE );
WndMenuEnable( wnd, MENU_FILE_SHOW_ADDRESS, TRUE );
WndMenuEnable( wnd, MENU_FILE_SHOW_MODULE, TRUE );
WndMenuEnable( wnd, MENU_FILE_FUNCTIONS, file->mod != NO_MOD );
WndMenuEnable( wnd, MENU_FILE_HOME, TRUE );
addr = GetRowAddr( file, row, FALSE );
WndMenuEnable( wnd, MENU_FILE_ASSEMBLY, !IS_NIL_ADDR( addr ) );
WndMenuEnable( wnd, MENU_FILE_WATCH, has_popitem );
WndMenuEnable( wnd, MENU_FILE_INSPECT, has_popitem );
WndMenuEnable( wnd, MENU_FILE_STEP_INTO, file->mod != NO_MOD && has_popitem );
WndMenuEnable( wnd, MENU_FILE_BREAK, has_popitem );
WndMenuEnable( wnd, MENU_FILE_RUN, has_addr );
WndMenuEnable( wnd, MENU_FILE_SKIP_TO_CURSOR, has_addr );
break;
case MENU_FILE_RUN:
GoToAddr( addr );
break;
case MENU_FILE_SKIP_TO_CURSOR:
SkipToAddr( addr );
break;
case MENU_FILE_BREAK:
BreakOnSelected( WndPopItem( wnd ) );
break;
case MENU_FILE_HOME:
GoHome();
break;
case MENU_FILE_SHOW_MODULE:
mod = file->mod;
if( DlgModName( LIT( New_Module ), &mod ) ) {
WndModInspect( mod );
}
break;
case MENU_FILE_SHOW_ADDRESS:
if( DlgCodeAddr( LIT( New_Addr ), &addr ) ) {
WndSrcInspect( addr );
}
break;
case MENU_FILE_STEP_INTO:
StepIntoFunction( WndPopItem( wnd ) );
break;
case MENU_FILE_INSPECT:
WndInspect( WndPopItem( wnd ) );
break;
case MENU_FILE_WATCH:
WndVarInspect( WndPopItem( wnd ) );
break;
case MENU_FILE_SEARCH:
WndSaveToHistory( SrchHistory, WndPopItem( wnd ) );
DbgWndSearch( wnd, FALSE, DlgSearch( wnd, SrchHistory ) );
break;
case MENU_FILE_ASSEMBLY:
AsmWndFind( file->asm, addr, file->track );
break;
case MENU_FILE_LINE:
GotoLine( wnd );
break;
case MENU_FILE_FUNCTIONS:
WndFuncInspect( file->mod );
break;
}
}
static void FilePosInit( a_window *wnd )
{
file_window *file = WndFile( wnd );
if( file->viewhndl == NULL ) {
file->size = 0;
} else {
file->size = FSize( file->viewhndl );
}
WndSetThumbPercent( wnd, 0 );
}
static void FilePos( a_window *wnd, int pos )
{
unsigned long range;
file_window *file = WndFile( wnd );
if( pos < 0 ) pos = 0;
if( file->viewhndl == NULL ) {
if( pos+WndRows(wnd) > file->eof ) return;
WndSetTop( wnd, pos );
return;
}
if( FReadLine( file->viewhndl, pos+WndRows(wnd), 0, TxtBuff, TXT_LEN ) < 0 ) {
pos = FCurrLine( file->viewhndl ) - WndRows(wnd) - 1;
if( pos < 0 ) {
pos = 0;
}
}
WndSetTop( wnd, pos );
if( pos >= file->rows ) {
file->rows = pos+1;
file->rows_offset = FLastOffset( file->viewhndl );
}
if( file->rows == 0 ) file->rows = 1;
if( file->rows_offset == 0 ) {
range = file->size;
} else {
range = file->size * file->rows / file->rows_offset;
}
WndSetVScrollRange( wnd, range );
WndSetThumbPos( wnd, pos );
}
static WNDSCROLL FileScroll;
static int FileScroll( a_window *wnd, int lines )
{
int old_top;
old_top = WndTop( wnd );
FilePos( wnd, old_top + lines );
return( WndTop( wnd ) - old_top );
}
static WNDMODIFY FileModify;
static void FileModify( a_window *wnd, int row, int piece )
{
file_window *file = WndFile( wnd );
address addr;
if( piece == PIECE_BREAK ) {
addr = GetRowAddr( file, row, TRUE );
if( IS_NIL_ADDR( addr ) ) return;
file->toggled_break = ( ( WndFlags & UP_BREAK_CHANGE ) == 0 );
ToggleBreak( addr );
WndRowDirty( wnd, row );
} else {
WndFirstMenuItem( wnd, row, piece );
}
}
static void FileSetDotAddr( a_window *wnd, address addr )
{
file_window *file = WndFile( wnd );
if( AddrComp( file->dotaddr, addr ) == 0 ) return;
file->dotaddr = addr;
if( IS_NIL_ADDR( addr ) ) return;
if( wnd == WndFindActive() ) {
AsmMoveDot( file->asm, addr );
SetCodeDot( addr );
}
}
static WNDNOTIFY FileNotify;
static void FileNotify( a_window *wnd, wnd_row row, int piece )
{
file_window *file = WndFile( wnd );
address addr;
piece = piece;
addr = GetRowAddr( file, row, FALSE );
if( IS_NIL_ADDR( addr ) ) return;
FileSetDotAddr( wnd, addr );
}
bool FileOpenGadget( a_window *wnd, wnd_line_piece *line, mod_handle mod )
{
a_window *curr;
for( curr = WndNext( NULL ); curr != NULL; curr = WndNext( curr ) ) {
if( WndClass( curr ) != WND_SOURCE ) continue;
if( mod == WndFile( curr )->mod ) {
if( line != NULL ) SetGadgetLine( wnd, line, GADGET_OPEN_SOURCE );
return( TRUE );
}
}
if( line != NULL ) SetGadgetLine( wnd, line, GADGET_CLOSED_SOURCE );
return( FALSE );
}
void FileBreakGadget( a_window *wnd, wnd_line_piece *line, bool curr, brk *bp )
{
if( curr ) {
if( bp == NULL ) {
SetGadgetLine( wnd, line, GADGET_CURRLINE );
} else if( bp->status.b.active ) {
SetGadgetLine( wnd, line, GADGET_CURRBREAK );
} else {
SetGadgetLine( wnd, line, GADGET_CURRDIMBREAK );
}
} else {
if( bp == NULL ) {
SetGadgetLine( wnd, line, GADGET_NOBREAK );
} else if( bp->status.b.active ) {
SetGadgetLine( wnd, line, GADGET_BREAK );
} else {
SetGadgetLine( wnd, line, GADGET_DIMBREAK );
}
}
}
static WNDGETLINE FileGetLine;
static bool FileGetLine( a_window *wnd, int row, int piece,
wnd_line_piece *line )
{
int len;
file_window *file = WndFile( wnd );
address addr;
brk *bp;
bool curr;
DIPHDL( cue, ch );
line->text = LIT( Empty );
if( file->viewhndl == NULL && ModHasInfo( file->mod, HK_CUE ) != DS_OK ) {
return( FALSE );
}
curr = ( row == file->active && ContextMod == file->mod );
switch( piece ) {
case PIECE_BREAK:
line->tabstop = FALSE;
if( row >= file->eof ) return( FALSE );
if( file->mod == NO_MOD ) return( TRUE );
addr = NilAddr;
if( !WndDoingSearch ) { // too expensive
addr = GetRowAddr( file, row, TRUE );
}
if( !IS_NIL_ADDR( addr ) ) {
bp = FindBreakByLine( file->mod, file->file_id, row+1 );
FileBreakGadget( wnd, line, curr, bp );
}
return( TRUE );
case PIECE_SOURCE:
line->text = TxtBuff;
line->extent = WND_MAX_EXTEND;
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?