%{
/*
 * Parser for command lines in the Wine debugger
 *
 * Copyright 1993 Eric Youngdale
 * Copyright 1995 Morten Welinder
 */

#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include "windows.h"
#include "debugger.h"

extern FILE * yyin;
unsigned int dbg_mode = 0;

static enum exec_mode dbg_exec_mode = EXEC_CONT;

void issue_prompt(void);
void mode_command(int);
void flush_symbols(void);
int yylex(void);
int yyerror(char *);

%}

%union
{
    DBG_ADDR         address;
    enum debug_regs  reg;
    char *           string;
    int              integer;
}

%token CONT STEP LIST NEXT QUIT HELP BACKTRACE INFO STACK SEGMENTS REGS
%token ENABLE DISABLE BREAK DELETE SET MODE PRINT EXAM DEFINE ABORT WALK
%token WND QUEUE 
%token NO_SYMBOL EOL
%token SYMBOLFILE

%token <string> IDENTIFIER
%token <integer> NUM FORMAT
%token <reg> REG

/* %left ',' */
/* %left '=' OP_OR_EQUAL OP_XOR_EQUAL OP_AND_EQUAL OP_SHL_EQUAL \
         OP_SHR_EQUAL OP_PLUS_EQUAL OP_MINUS_EQUAL \
         OP_TIMES_EQUAL OP_DIVIDE_EQUAL OP_MODULO_EQUAL */
/* %left OP_COND */ /* ... ? ... : ... */
%left OP_LOR
%left OP_LAND
%left '|'
%left '^'
%left '&'
%left OP_EQ OP_NE
%left '<' '>' OP_LE OP_GE
%left OP_SHL OP_SHR
%left '+' '-'
%left '*' '/' '%'
%left OP_SIGN '!' '~' OP_DEREF /* OP_INC OP_DEC OP_ADDR */
%nonassoc ':'

%type <integer> expr
%type <address> addr segaddr symbol

%%

 input:   line			{ issue_prompt(); }
	| input line		{ issue_prompt(); }

 line:  command 
	| EOL
	| error	EOL	       { yyerrok; }

 command: QUIT EOL             { exit(0); }
	| HELP EOL             { DEBUG_Help(); }
	| CONT EOL             { dbg_exec_mode = EXEC_CONT; return 0; }
	| STEP EOL             { dbg_exec_mode = EXEC_STEP_INSTR; return 0; }
	| NEXT EOL             { dbg_exec_mode = EXEC_STEP_OVER; return 0; }
	| LIST EOL	       { DEBUG_List( NULL, 15 ); }
	| LIST addr EOL	       { DEBUG_List( &$2, 15 ); }
	| ABORT	EOL            { kill(getpid(), SIGABRT); }
	| SYMBOLFILE IDENTIFIER EOL  { DEBUG_ReadSymbolTable( $2 ); }
	| DEFINE IDENTIFIER addr EOL { DEBUG_AddSymbol( $2, &$3 ); }
	| MODE NUM EOL	       { mode_command($2); }
	| ENABLE NUM EOL       { DEBUG_EnableBreakpoint( $2, TRUE ); }
	| DISABLE NUM EOL      { DEBUG_EnableBreakpoint( $2, FALSE ); }
	| BREAK '*' addr EOL   { DEBUG_AddBreakpoint( &$3 ); }
	| BREAK symbol EOL     { DEBUG_AddBreakpoint( &$2 ); }
	| BREAK EOL	       { DBG_ADDR addr = { CS_reg(DEBUG_context),
						     EIP_reg(DEBUG_context) };
				 DEBUG_AddBreakpoint( &addr );
			       }
	| DELETE BREAK NUM EOL { DEBUG_DelBreakpoint( $3 ); }
	| BACKTRACE EOL	       { DEBUG_BackTrace(); }
	| WALK WND EOL	       { DEBUG_InitWalk(); DEBUG_WndWalk( NULL ); }
	| WALK WND NUM EOL     { DEBUG_InitWalk(); DEBUG_WndWalk( $3 ); }
	| infocmd
	| x_command
	| print_command
	| deposit_command

deposit_command:
	SET REG '=' expr EOL	      { DEBUG_SetRegister( $2, $4 ); }
	| SET '*' addr '=' expr	EOL   { DEBUG_WriteMemory( &$3, $5 ); }
	| SET IDENTIFIER '=' addr EOL { if (!DEBUG_SetSymbolValue( $2, &$4 ))
				         {
					   fprintf( stderr,
						 "Symbol %s not found\n", $2 );
					   YYERROR;
				         }
				       }


x_command:
	  EXAM addr EOL         { DEBUG_ExamineMemory( &$2, 1, 'x'); }
	| EXAM FORMAT addr EOL  { DEBUG_ExamineMemory( &$3, $2>>8, $2&0xff ); }

 print_command:
	  PRINT addr EOL        { DEBUG_Print( &$2, 1, 'x' ); }
	| PRINT FORMAT addr EOL { DEBUG_Print( &$3, $2 >> 8, $2 & 0xff ); }

 symbol: IDENTIFIER   { if (!DEBUG_GetSymbolValue( $1, &$$ ))
			{
			   fprintf( stderr, "Symbol %s not found\n", $1 );
			   YYERROR;
			}
		      } 

 addr: expr				{ $$.seg = 0xffffffff; $$.off = $1; }
       | segaddr			{ $$ = $1; }

 segaddr: expr ':' expr			{ $$.seg = $1; $$.off = $3; }
       | symbol				{ $$ = $1; }

 expr:	NUM				{ $$ = $1;	}
	| REG				{ $$ = DEBUG_GetRegister($1); }
	| expr OP_LOR expr		{ $$ = $1 || $3; }
	| expr OP_LAND expr		{ $$ = $1 && $3; }
	| expr '|' expr			{ $$ = $1 | $3; }
	| expr '&' expr			{ $$ = $1 & $3; }
	| expr '^' expr			{ $$ = $1 ^ $3; }
	| expr OP_EQ expr		{ $$ = $1 == $3; }
	| expr '>' expr			{ $$ = $1 > $3; }
	| expr '<' expr			{ $$ = $1 < $3; }
	| expr OP_GE expr		{ $$ = $1 >= $3; }
	| expr OP_LE expr		{ $$ = $1 <= $3; }
	| expr OP_NE expr		{ $$ = $1 != $3; }
	| expr OP_SHL expr		{ $$ = (unsigned)$1 << $3; }
	| expr OP_SHR expr		{ $$ = (unsigned)$1 >> $3; }
	| expr '+' expr			{ $$ = $1 + $3; }
	| expr '-' expr			{ $$ = $1 - $3; }
	| expr '*' expr			{ $$ = $1 * $3; }
	| expr '/' expr
	  { if ($3) 
	      if ($3 == -1 && $1 == 0x80000000l)
		yyerror ("Division overflow");
	      else
		$$ = $1 / $3;
	    else
	      yyerror ("Division by zero"); }
	| expr '%' expr
	  { if ($3) 
	      if ($3 == -1 && $1 == 0x80000000l)
		$$ = 0; /* A sensible result in this case.  */
	      else
		$$ = $1 % $3;
	    else
	      yyerror ("Division by zero"); }
	| '-' expr %prec OP_SIGN	{ $$ = -$2; }
	| '+' expr %prec OP_SIGN	{ $$ = $2; }
	| '!' expr			{ $$ = !$2; }
	| '~' expr			{ $$ = ~$2; }
	| '(' expr ')'			{ $$ = $2; }
/* For parser technical reasons we can't use "addr" here.  */
	| '*' expr %prec OP_DEREF	{ DBG_ADDR addr = { 0xffffffff, $2 };
					  $$ = DEBUG_ReadMemory( &addr ); }
	| '*' segaddr %prec OP_DEREF	{ $$ = DEBUG_ReadMemory( &$2 ); }
	
 infocmd: INFO REGS EOL	          { DEBUG_InfoRegisters(); }
	| INFO STACK EOL          { DEBUG_InfoStack(); }
	| INFO BREAK EOL          { DEBUG_InfoBreakpoints(); }
	| INFO SEGMENTS EOL	  { LDT_Print( 0, -1 ); }
	| INFO SEGMENTS expr EOL  { LDT_Print( SELECTOR_TO_ENTRY($3), 1 ); }
	| INFO WND expr EOL       { DEBUG_WndDump( $3 ); } 
	| INFO QUEUE expr EOL     { DEBUG_QueueDump( $3 ); }


%%

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

void mode_command(int newmode)
{
    if ((newmode == 16) || (newmode == 32)) dbg_mode = newmode;
    else fprintf(stderr,"Invalid mode (use 16 or 32)\n");
}


void wine_debug( int signal, struct sigcontext_struct *regs )
{
    static int loaded_symbols = 0;
    char SymbolTableFile[256];
    int instr_len = 0, newmode;
#ifdef YYDEBUG
    yydebug = 0;
#endif

    yyin = stdin;
    DEBUG_context = (struct sigcontext_struct *)regs;

    DEBUG_SetBreakpoints( FALSE );

    if (!loaded_symbols)
    {
        loaded_symbols++;
        PROFILE_GetWineIniString( "wine", "SymbolTableFile", "wine.sym",
                                  SymbolTableFile, sizeof(SymbolTableFile) );
        DEBUG_ReadSymbolTable( SymbolTableFile );
        DEBUG_LoadEntryPoints();
    }

    if ((signal != SIGTRAP) || !DEBUG_ShouldContinue( regs, dbg_exec_mode ))
    {
        DBG_ADDR addr;

        addr.seg = CS_reg(DEBUG_context);
        addr.off = EIP_reg(DEBUG_context);
        DBG_FIX_ADDR_SEG( &addr, 0 );

        if (!addr.seg) newmode = 32;
        else newmode = (GET_SEL_FLAGS(addr.seg) & LDT_FLAGS_32BIT) ? 32 : 16;

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

        if (signal != SIGTRAP)  /* This is a real crash, dump some info */
        {
            DEBUG_InfoRegisters();
            DEBUG_InfoStack();
            if (dbg_mode == 16)
            {
                LDT_Print( SELECTOR_TO_ENTRY(DS_reg(DEBUG_context)), 1 );
                if (ES_reg(DEBUG_context) != DS_reg(DEBUG_context))
                    LDT_Print( SELECTOR_TO_ENTRY(ES_reg(DEBUG_context)), 1 );
            }
            DEBUG_BackTrace();
        }

        /* Show where we crashed */
        DEBUG_PrintAddress( &addr, dbg_mode );
        fprintf(stderr,":  ");
        if (DBG_CHECK_READ_PTR( &addr, 1 ))
        {
            DEBUG_Disasm( &addr );
            fprintf(stderr,"\n");
            instr_len = addr.off - EIP_reg(DEBUG_context);
        }

        do
        {
            issue_prompt();
            yyparse();
            flush_symbols();
            addr.seg = CS_reg(DEBUG_context);
            addr.off = EIP_reg(DEBUG_context);
            DBG_FIX_ADDR_SEG( &addr, 0 );
        } while (!DBG_CHECK_READ_PTR( &addr, 1 ));
    }

    DEBUG_RestartExecution( regs, dbg_exec_mode, instr_len );
}


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

