📄 yydebug.c
字号:
fprintf(Log, " +---+------------------+\n");
}
else
{
if( state < Sstack )
fprintf( Log,"*** Stack empty ***\n");
else
{
/* Print horizontal stack pictures. Note that you have to go
* through the stack from bottom to top to get the top-of-stack
* element on the right.
*/
for( i = 0; i <= 2; ++i )
{
if( !Parse_pix && i == 0 ) continue;
if( !Sym_pix && i == 1 ) continue;
if( !Attr_pix && i == 2 ) continue;
switch( i )
{
case 0: fprintf( Log, " PARSE " ); break;
case 1: fprintf( Log, " SYMBOL " ); break;
case 2: fprintf( Log, " ATTRIB " ); break;
}
toss = Sstack + (Depth - 1);
tods = Dstack + (Depth - 1);
tovs = Vstack + ((Depth - 1) * Vsize);
for(; toss >= state; --toss, --tods, tovs -= Vsize )
{
/* Find width of the column. I'm assuming that the
* numbers on the state stack are at most 3 digits
* long, if not, change the 3, below.
*/
p = yypstk( tovs, *tods );
width = 3;
if( Sym_pix ) width = max( width, strlen(*tods) );
if( Attr_pix ) width = max( width, strlen(p) );
switch( i )
{
case 0: fprintf( Log, "%-*d ", width, *toss ); break;
case 1: fprintf( Log, "%-*s ", width, *tods ); break;
case 2: fprintf( Log, "%-*s ", width, p ); break;
}
}
fputc( '\n', Log );
}
}
}
}
if( !Interactive )
{
if( ++times_called % 25 == 0 )
{
wprintw ( Stack_window, "working: %d\r", times_called );
wrefresh( Stack_window );
}
return;
}
if( *S_breakpoint && state < Sstack + Depth )
{
/* Break if the breakpoint is a digit and the top-of-stack item has that
* value, or if the string matches the string currently at the top of
* the symbol stack.
*/
if( isdigit(*S_breakpoint) )
{
if( atoi(S_breakpoint) == *state )
Singlestep = 1;
}
else if( !strcmp(S_breakpoint, *debug) )
Singlestep = 1;
}
if( do_refresh )
yy_redraw_stack(); /* Redraw entire stack */
else if( numele > Onumele )
{
/* The stack has grown. Redraw only those parts of the stack that have
* changed. (I'm assuming only by one element.) The main difficulty
* here is that only the top few elements of a large stack are
* displayed. Consequently, the stack window may have to scroll up
* or down a line if the stack size is hovering around the window size.
* There's no portable way to scroll the window up under UNIX curses, so
* we have to redraw the stack to scroll up in this situation. We'll
* overwrite the top element with itself by the wprintw() call, but
* that's no big deal, and it simplifies the code.
*/
if( numele > Stacksize ) /* scroll down, opening up top line */
{
MS ( wscroll( Stack_window, -1 ); )
UNIX( yy_redraw_stack(); )
wmove( Stack_window, 0, 0 );
}
else
wmove( Stack_window, Stacksize - numele, 0 );
wprintw( Stack_window, "%3d%c %16.16s %c %1.52s",
*state, VERT, *debug, VERT, yypstk(value, *debug) );
wrefresh( Stack_window );
}
else
{
/* The stack has shrunk, perhaps by several elements. Remove them one at
* a time. (It's too confusing if several elements disappear from the
* stack at once. It's best to watch them go one at a time.) If the
* number of elements on the stack (i) is greater than the window size,
* you can pop an element by scrolling up and then writing in a new
* bottom line, otherwise, just go to the correct line and erase it.
* Do a refresh after each pop.
*/
for( i = Onumele; i > numele; --i )
{
if( i > Stacksize )
{
/* Do a pop by scrolling up, the easiest way to scroll is to
* move to the right edge of the bottom line and then issue
* a newline. After the scroll, overwrite the now-blank bottom
* line with the appropriate stack information. The involved
* expression that is the first argument to yypstk is doing:
* (Vstack + Depth)[ -i + Stacksize ]
* It must do the pointer arithmetic explicitly, however, by
* multiplying by the size of one value-stack item (Vsize).
*/
wmove ( Stack_window, Stacksize-1, 77 );
NEWLINE ( Stack_window );
wprintw ( Stack_window, "%3d%c %16.16s %c %1.52s",
(Sstack + Depth)[ -i + Stacksize ], VERT,
(Dstack + Depth)[ -i + Stacksize ], VERT,
yypstk( (Vstack + (Depth*Vsize)) +
((-i + Stacksize) * Vsize),
(Dstack + Depth)[ -i + Stacksize ] )
);
}
else
{
wmove ( Stack_window, Stacksize - i, 0 );
wclrtoeol( Stack_window );
}
wrefresh( Stack_window );
}
}
delay();
wrefresh( Stack_window );
Onumele = numele;
}
/*----------------------------------------------------------------------*/
PUBLIC void yy_redraw_stack()
{
/* Redraw the entire stack screen by writing out the top Stacksize elements
* of the stack in the stack window. Note that scrolling is turned off so
* that the screen won't scroll when you print the last line. Unlike
* yy_pstack(), this routine won't pause for a command.
*/
int i;
int numele; /* Number of elements on the stack */
int *state = *P_sp; /* Pointer to top of state stack */
char **debug = *P_dsp; /* Pointer to top of debug stack */
char *value; /* Pointer to top of value stack */
werase ( Stack_window );
scrollok ( Stack_window, FALSE );
numele = Depth - (state - Sstack);
value = Vstack + ((Depth - numele) * Vsize);
wmove( Stack_window, numele <= Stacksize ? Stacksize - numele : 0, 0 );
for( i=min(Stacksize, numele); --i >= 0; ++state, ++debug, value += Vsize )
wprintw( Stack_window, "%3d%c %16.16s %c %1.52s\n",
*state, VERT,
*debug, VERT, yypstk(value, *debug) );
scrollok( Stack_window, TRUE );
}
PRIVATE void delay()
{
/* Print a prompt and wait for either a carriage return or another command.
* Note that the time returned by time() is the elapsed time, in seconds,
* from 00:00:00, January 1, 1970 GMT. Since there are roughly 31,557,600
* seconds in a year (365.25 * 24 * 60 * 60) and the largest (signed)
* 32-bit long int can hold 2,147,483,647, the time won't roll over until
* January 18, 2038 at 2:56:02 A.M. Don't use this program on January 18,
* 2038 at 2:56:02 A.M.
*/
long start, current;
char buf[80];
int print_lines;
struct timeb time_buf; /* defined in sys/timeb.h */
if( !Interactive ) /* n command (noninteractive) issued */
return;
if( !Singlestep && kbhit() )
{
/* If we're not single stepping (a 'g' command has been issued) and
* there's a key pressed, stop single stepping and get the character.
*/
input_char();
Singlestep = 1;
}
if( !Singlestep )
{
/* If we're still doing a go command (no key was found in the previous
* if statement), then delay for a while. Must use two if statements
* here because we don't want to delay if we've just stopped go-ing.
* If a key is hit while we're delaying, stop looping immediately and
* revert back to single-step mode.
*/
ftime( &time_buf );
start = (time_buf.time * 1000) + time_buf.millitm;
while( 1 )
{
ftime( &time_buf );
current = (time_buf.time * 1000) + time_buf.millitm;
if( current - start >= Delay )
break;
if( kbhit() ) /* If a key is hit, stop delaying */
{ /* and revert back to single-step */
input_char(); /* mode. */
Singlestep = 1;
break;
}
}
if( !Singlestep ) /* If we're still not single stepping, then */
return; /* we're done (don't get a command), */
/* otherwise, fall out of this block and */
/* enter the command loop, below. */
}
while( 1 )
{
yyprompt( "Enter command (space to continue, ? for list): ", buf, 0 );
switch( *buf )
{
case '\0' :
case ' ' :
case '\n' : /* singlestep */
goto outside;
case '?' : /* help */
cmd_list();
NEWLINE ( Prompt_window );
presskey();
yy_redraw_stack();
break;
case 'a': /* abort */
Abort = 1;
Singlestep = 0;
goto outside;
case 'b': /* breakpoints */
breakpoint();
yy_redraw_stack();
break;
case 'd': /* set delay time */
if(yyprompt("Delay time (in seconds, CR=0, ESC cancels): ", buf,1))
Delay = (long)( atof(buf) * 1000.0 );
break;
case 'f': /* read file */
if( !yyprompt( "Print line numbers? (y/n, CR=y, ESC cancels): ",
buf, 0))
break;
print_lines = *buf != 'n';
if( !yyprompt( "File name or ESC to cancel: ", buf, 1) )
break;
werase( Stack_window );
display_file( buf, sizeof(buf), print_lines );
yy_redraw_stack();
break;
case 'g': /* go! */
Singlestep = 0;
goto outside;
case 'i':
if( yyprompt( "Input file name or ESC to cancel: ", buf, 1 ) )
new_input_file( buf );
break;
case 'l': /* enable logging */
to_log( buf );
break;
case 'N': /* noninteractive w/o logging */
Log = NULL;
No_stack_pix = 1;
Interactive = 0;
Singlestep = 0;
Delay = 0L;
werase( Stack_window );
goto outside;
case 'n': /* noninteractive mode w/ log */
if( !Log && !to_log(buf) )
break;
Interactive = 0;
Singlestep = 0;
Delay = 0L;
werase( Stack_window );
goto outside;
case 'q': /* exit to operating system */
raise( SIGINT ); /* as if Ctrl-C was entered */
exit(0);
case 'r': /* redraw the stack window */
yy_redraw_stack();
break;
case 'w': /* write screen to file */
if( yyprompt( "Output file name or ESC to cancel: ", buf, 1) )
write_screen( buf );
break;
case 'x': /* show lexemes */
yycomment( "current [%0.*s]\n", yyleng, yytext );
yycomment( "previous [%0.*s]\n", ii_plength(), ii_ptext() );
break;
case 0x01: yyhook_a(); break; /* Ctrl-A debugger hook (see text) */
case 0x02: yyhook_b(); break; /* Ctrl-B */
default:
yyprompt( "Illegal command, press any key to continue", buf, 0 );
break;
}
}
outside:
werase ( Prompt_window );
wrefresh( Prompt_window );
}
/*----------------------------------------------------------------------*/
PRIVATE void cmd_list()
{
/* Print a list of commands in the stack window & prompt for an action. */
werase (Stack_window );
wmove (Stack_window, 0, 0 );
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -