
%{

/* Parser for command lines in the Wine debugger
 *
 * Version 1.0
 * Eric Youngdale
 * 9/93
 */

#include <stdio.h>
#include <signal.h>
#include "ldt.h"
#include "windows.h"
#include "wine.h"

#define YYSTYPE int

#include "regpos.h"
extern FILE * yyin;
unsigned int * regval = NULL;
unsigned int dbg_mask = 0;
unsigned int dbg_mode = 0;

void issue_prompt(void);
void mode_command(int);
%}


%token CONT
%token QUIT
%token HELP
%token BACKTRACE
%token INFO
%token STACK
%token SEGMENTS
%token REG
%token REGS
%token NUM
%token ENABLE
%token DISABLE
%token BREAK
%token SET
%token MODE
%token PRINT
%token IDENTIFIER
%token NO_SYMBOL
%token SYMBOLFILE
%token DEFINE
%token ABORT

%%

 input:  /* empty */
	| input line  { issue_prompt(); }

 line:		'\n'
	| infocmd '\n'
	| error '\n'       { yyerrok; }
	| QUIT  '\n'       { exit(0); }
	| 'q' '\n'         { exit(0); }
	| HELP  '\n'       { dbg_help(); }
	| CONT '\n'        { return 0; }
	| 'c' '\n'         { return 0; }
	| ABORT '\n'       { kill(getpid(), SIGABRT); }
 	| SYMBOLFILE IDENTIFIER '\n' { read_symboltable($2); }
	| DEFINE IDENTIFIER expr '\n'  { add_hash($2, 0, $3); }
	| MODE NUM	   { mode_command($2); }
	| ENABLE NUM	   { enable_break($2); }
	| DISABLE NUM	   { disable_break($2); }
	| BREAK '*' expr   { add_break($3); }
	| x_command
	| BACKTRACE '\n'   { dbg_bt(); }
	| print_command
	| deposit_command

deposit_command:
	SET REG '=' expr '\n' { if(regval) regval[$2] = $4; else application_not_running();}
	| SET '*' expr '=' expr '\n' { *((unsigned int *) $3) = $5; }
	| SET symbol '=' expr '\n' { *((unsigned int *) $2) = $4; }


x_command:
	  'x' expr  '\n' { examine_memory( 0xffffffff, $2, 1, 'x'); }
	| 'x' '/' fmt expr  '\n' { examine_memory( 0xffffffff, $4, 1, $3); }
	| 'x' '/' NUM fmt expr  '\n' { examine_memory( 0xffffffff, $5, $3, $4); }

print:
	  'p'
	| PRINT
	
 print_command:
	  print expr '\n' { examine_memory( 0, ((unsigned int) &$2 ), 1, 'x'); }
	| print '/' fmt expr '\n' { examine_memory( 0, (unsigned int) &$4, 1, $3); }

 fmt:  'x'     { $$ = 'x'; }
	| 'd'  { $$ = 'd'; }
	| 'i'  { $$ = 'i'; }
	| 'w'  { $$ = 'w'; }
	| 's'  { $$ = 's'; }
	| 'c'  { $$ = 'c'; }
	| 'b' { $$ = 'b'; }

 symbol: IDENTIFIER             { $$ = find_hash($1);
			           if($$ == 0xffffffff) {
					   fprintf(stderr,"Symbol %s not found\n", $1);
					   YYERROR;
				   }
			        } 

 expr:  NUM			{ $$ = $1;	}
	| REG			{ if(regval) $$ = regval[$1]; else application_not_running();}
	| symbol   		{ $$ = $1; }
	| expr '+' NUM		{ $$ = $1 + $3; }
	| expr '-' NUM		{ $$ = $1 - $3; }
	| '(' expr ')'		{ $$ = $2; }
	| '*' expr		{ $$ = *((unsigned int *) $2); }
	
 infocmd: INFO REGS     { info_reg(); }
	| INFO STACK    { info_stack(); }
	| INFO SEGMENTS { LDT_Print(); }
	| INFO BREAK    { info_break(); }


%%

void 
issue_prompt(){
#ifndef USE_READLINE
	fprintf(stderr,"Wine-dbg>");
#endif
}

void mode_command(int newmode)
{
  if(newmode == 16){
    dbg_mask = 0xffff;
    dbg_mode = 16;
    return;
  }
  if(newmode == 32){ 
    dbg_mask = 0xffffffff;
    dbg_mode = 32;
    return;
  }
  fprintf(stderr,"Invalid mode (use 16 or 32)\n");
}

static int loaded_symbols = 0;

void
wine_debug(int signal, int * regs)
{
	static int dummy_regs[32];
	char SymbolTableFile[256];
#ifdef YYDEBUG
	yydebug = 0;
#endif

	yyin = stdin;
	regval = regs ? regs : dummy_regs;

	if (SC_CS == WINE_CODE_SELECTOR) dbg_mode = 32;
        else dbg_mode = (GET_SEL_FLAGS(SC_CS) & LDT_FLAGS_32BIT) ? 32 : 16;
        dbg_mask = (dbg_mode == 32) ? 0xffffffff : 0xffff;

	fprintf(stderr,"In %d bit mode.\n", dbg_mode);

	if(dbg_mode == 32 && !loaded_symbols)
        {
		loaded_symbols++;
		GetPrivateProfileString("wine", "SymbolTableFile", "wine.sym",
			SymbolTableFile, sizeof(SymbolTableFile), WINE_INI);
		read_symboltable(SymbolTableFile);
	}

	/* Remove the breakpoints from memory... */
	insert_break(0);

	/* If we stopped on a breakpoint, report this fact */
	if(signal == SIGTRAP)
	  {
	    unsigned int addr;
	    int bpnum;
	    addr = SC_EIP(dbg_mask);
	    if (dbg_mode == 16) addr = PTR_SEG_OFF_TO_LIN( SC_CS, addr );
	    if(should_continue(bpnum=get_bpnum(addr))){
		insert_break(1);
		return;
	    }
	    fprintf(stderr,"Stopped on breakpoint %d\n", bpnum);
	  }

	/* Show where we crashed */
	if(regs)
	  examine_memory(0xffffffff, SC_EIP(dbg_mask), 1, 'i');

	issue_prompt();

	yyparse();
	flush_symbols();

	/* Re-insert the breakpoints from memory... */
	insert_break(1);

	fprintf(stderr,"Returning to Wine...\n");

}


int yyerror(char * s)
{
	fprintf(stderr,"%s\n", s);
        return 0;
}

