📄 yydebug.c
字号:
filename = *newargv++ = *argv;
break;
}
else if( argv[0][1] == 's' ) /* -s */
ssize = atoi( &argv[0][2] ); /* Don't copy to *newargv here. */
else /* -? */
*newargv++ = *argv;
}
Stacksize = ( ssize < 1 ) ? DEFSTACK :
( ssize > (SCRNSIZE-6) ) ? SCRNSIZE-6 :
/* ssize is in bounds */ ssize ;
if( filename )
{
/* Open input file if one was specified on the command line. */
if( ii_newfile(filename) != -1 )
Inp_fm_file = 1;
else
{
perror( filename );
exit( 1 );
}
}
return newargv - oldargv;
}
ANSI( PRIVATE int prnt_putc(int c, WINDOW *win) )
KnR ( PRIVATE int prnt_putc( c, win) )
KnR ( int c; )
KnR ( WINDOW *win; )
{
/* All output done through prnt_putc is suppressed in Go mode. Also note
* that the arguments are reversed from addch(). This reversal lets you use
* the prnt() subroutine (described in Appendix A), which expects a putc()-
* like output function. Newlines are suppressed here so that you can have
* more control over scrolling. Similarly, sequences of white space are
* replaced by a single space character to conserve space in the window.
* Test_c is used to take care of the IBM graphics characters that form
* the vertical line separating the stream-identification column from the
* actual output. The c is mapped to a '|' if it's too large to be an ASCII
* character (so isspace() will work properly).
*/
static WINDOW *last_win = NULL;
static int last_c = 0;
int test_c;
if( Interactive && c != '\n' )
{
test_c = (c < 0x7f) ? c : '|';
if( !(win==last_win && isspace(test_c) && isspace(last_c)) )
waddch( win, isspace(test_c) ? ' ' : c );
last_win = win;
last_c = test_c;
}
return c; /* keeps the compiler happy by returning a value a'la putc */
}
/*----------------------------------------------------------------------*/
#ifdef MSDOS
# define refresh_win(win) /* empty */
#else /* UNIX */
PRIVATE void refresh_win( win )
WINDOW *win;
{
/* Refresh the windows if you're not in go mode. (If you are, nothing
* will have been written, so there's not point in doing the refresh.
*/
if( Interactive )
wrefresh( win );
}
#endif
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
PUBLIC void yy_output( where, fmt, args ) /* Generate code */
int where;
char *fmt;
va_list args;
{
/* Works like vprintf(), but sends output to the code window. In the window,
* it ignores any newlines in the string but prints a newline after every
* call. All code sent to yycode(), yydata(), and yybss() is funneled
* here. "where" should be one of the following:
*
* 0 : code
* 1 : data
* 2 : bss
*
* Note that if the three associated streams (yycodeout, yybssout, and
* yydataout--all declared in the parser output file) are not directed to
* stdout, output is sent to that stream TOO. Don't modify these to point
* at stderr (or any other stream that accesses the console: /dev/tty, con,
* etc.) or you'll mess up the screen.
*
* Note that the real yycode(), etc (ie. the ones supplied when YYDEBUG
* is not defined) don't do anything special with newlines. In particular,
* they are not inserted automatically at the end of the line. To make both
* sets of routines compatible, your output strings should all have exactly
* one newline, placed at the end of the string (don't imbed any in the
* middle).
*/
extern FILE *yycodeout, *yydataout, *yybssout;
if( Log )
{
fprintf( Log, where == 0 ? "CODE->" :
where == 1 ? "DATA->" : "BSS-->" );
prnt ( (prnt_t) fputc, Log, fmt, args );
fputc( '\n', Log );
}
NEWLINE( Code_window );
prnt_putc( where==0 ? 'C' : where==1 ? 'D' : 'B', Code_window );
prnt_putc( VERT, Code_window );
prnt( (prnt_t) prnt_putc, Code_window, fmt, args );
refresh_win( Code_window );
if( where == 0 && yycodeout != stdout )
vfprintf( yycodeout, fmt, args );
if( where == 1 && yydataout != stdout )
vfprintf( yydataout, fmt, args );
if( where == 2 && yybssout != stdout )
vfprintf( yybssout, fmt, args );
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ANSI( PUBLIC void yycomment( char *fmt, ... ) )
KnR ( PUBLIC yycomment( fmt ) )
KnR ( char *fmt; )
{
/* Works like printf() except that it automatically prints a newline
* IN FRONT OF the string and ignores any \n's in the string itself. Writes
* into the comment window, and outputs a message to the log file if
* logging is enabled.
*/
va_list args;
va_start( args, fmt );
if( Log && !No_comment_pix )
prnt( (prnt_t) fputc, Log, fmt, args );
NEWLINE( Comment_window );
prnt( (prnt_t) prnt_putc, Comment_window, fmt, args );
refresh_win( Comment_window );
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ANSI( PUBLIC void yyerror( char *fmt, ... ) )
KnR ( PUBLIC yyerror( fmt ) )
KnR ( char *fmt; )
{
/* Debugging version of the error routine. Works just like the nondebugging
* version, but writes to the comment window. Note that yycomment() copies
* the error message to the Log file. Interactive mode is temporarily
* enabled to assure that error messages get printed.
*/
int old_interactive;
va_list args;
va_start( args, fmt );
old_interactive = Interactive;
Interactive = 1;
yycomment( "ERROR, line %d near <%s>\n", yylineno, yytext );
if( Log )
prnt( (prnt_t) fputc, Log, fmt, args );
NEWLINE ( Comment_window );
prnt ( (prnt_t) prnt_putc, Comment_window, fmt, args );
refresh_win ( Comment_window );
Interactive = old_interactive;
Singlestep = 1; /* Force a breakpoint */
yy_pstack( 0, 1 );
}
/*- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - */
ANSI( PUBLIC void yy_input( char *fmt, ... ) )
KnR ( PUBLIC yy_input( fmt ) )
KnR ( char *fmt; )
{
/* This is not an input function; rather, it writes to the INPUT window.
* It works like printf(). Note that nothing is logged here. The logging
* is done in nextoken(). Ignores all \n's in the input string.
*/
va_list args;
va_start( args, fmt );
prnt( (prnt_t) prnt_putc, Prompt_window, fmt, args );
refresh_win( Prompt_window );
}
/*----------------------------------------------------------------------*/
PRIVATE void display_file( name, buf_size, print_lines )
char *name; /* Initially holds the file name, but */
int buf_size; /* recycled as an input buffer. */
int print_lines;
{
/* Display an arbitrary file in the stack window, one page at a time.
* The stack window is not refreshed by this routine.
*/
FILE *fd;
int i;
int lineno = 0;
if( !(fd = fopen( name, "r")) )
{
NEWLINE ( Prompt_window );
wprintw ( Prompt_window, "Can't open %s", name );
wrefresh ( Prompt_window );
presskey ();
}
else /* Note that order of evaluation is important in */
{ /* the following while statement. You don't want */
/* to get the line if i goes past 0. */
for( i = Stacksize-1 ;; i = (*name == ' ') ? 1 : Stacksize - 2 )
{
while( --i >= 0 && fgets(name, buf_size, fd) )
{
if( print_lines )
wprintw( Stack_window, "%3d:", ++lineno );
wprintw ( Stack_window, "%s", name );
wrefresh( Stack_window );
}
if( i > 0 )
break;
if(!yyprompt("ESC quits. Space scrolls 1 line. Enter for screenful",
name, 0) )
break;
}
yyprompt("*** End of file. Press any key to continue ***", name, 0 );
fclose( fd );
}
}
/*----------------------------------------------------------------------*/
PRIVATE void write_screen( filename )
char *filename;
{
/* Print the current screen contents to the indicated file. Note that the
* right edge of the box isn't printed in order to let us have 79-character
* lines. Otherwise, the saved screen shows up as double-spaced on most
* printers. The screen image is appended to the end of the file. In MS-DOS,
* Use "prn:" as the file name if you want to go to the printer.
*
* Syserrlist and errno are both defined in <stdlib.h>
*/
char buf[2];
char *mode = "a";
int row, col, y, x;
FILE *file;
if( access( filename, 0 ) == 0 )
if( !yyprompt("File exists, overwrite or append? (o/a): ", buf, 0) )
{
NEWLINE ( Prompt_window );
yy_input( "Aborting command." );
presskey();
return;
}
else
{
if( toupper(*buf) == 'O' )
mode = "w";
}
if( file = fopen( filename, mode) )
yy_input("...%s %s...",
*mode=='w' ? "overwriting" : "appending to", filename );
else
{
yy_input( "Can't open %s.", filename );
MSC( yy_input( "(%s)", sys_errlist[errno]); )
presskey();
return;
}
getyx( Prompt_window, y, x );
for( row = 0; row < SCRNSIZE; row++ )
{
for( col = 0; col < PRINTWIDTH; col++ )
{
MS ( fputc( conv( mvinch(row,col) ), file ); )
UNIX( fputc( mvinch(row,col) , file ); )
}
fputc( '\n', file );
}
fclose( file );
wmove( Prompt_window, y, x );
}
PUBLIC void yy_pstack( do_refresh, print_it )
int do_refresh; /* redraw entire window rather than update */
int print_it; /* if true, print the stack to the log file */
{
/* Print the state, debug, and value stacks.
*
* The library routine yypstk() (which returns an empty string by default)
* is called to print value stack items. It should return a pointer to a
* string that represents the value-stack contents. Just provide a similarly
* named routine to print your real value stack. The LLAMA parser passes
* garbage to yypstk(), so use the default routine in LLAMA. The OCCS parser
* passes yypstk() a pointer to a value-stack item and it should return a
* pointer to a string representing attributes of interest. The line should
* not contain any newlines and it should be at most 58 characters long.
* If do_refresh is true, the entire stack window is redrawn, otherwise
* only those parts of the window that have been changed are modified.
*/
int numele ; /* # of elements on the stack */
int *toss ; /* top of state stack */
char **tods ; /* top of debug stack */
char *tovs ; /* top of value stack */
int *state ; /* current state-stack pointer */
char **debug ; /* current debug-stack pointer */
char *value ; /* current value-stack pointer */
int width ; /* Width of column in horiz. stack */
static int times_called = -1 ; /* # of times this subroutine called */
char *p ;
int i ;
state = *P_sp;
debug = *P_dsp;
numele = Depth - (state - Sstack);
value = (Vstack + (Depth - numele) * Vsize);
if( Log && !No_stack_pix && print_it )
{
/* Print the stack contents out to the log file. */
if( !Horiz_stack_pix )
{
fprintf(Log, " +---+------------------+\n");
if( numele <= 0 )
fprintf( Log," * | * | ************ | Stack is empty.\n");
else
{
toss = state;
tods = debug;
tovs = value;
for(i = numele; --i >= 0; ++toss, ++tods, tovs += Vsize )
fprintf( Log, "%3d|%3d| %16.16s | %1.52s\n",
toss - state, *toss, *tods, yypstk(tovs, *tods));
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -