%{
/*
 * 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
%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(); }
	| 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 ); }


%%

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;
}

