debugger_expression* debugger_expression_copy( debugger_expression *src ) { debugger_expression *dest; dest = malloc( sizeof( *dest ) ); if( !dest ) return NULL; dest->type = src->type; dest->precedence = src->precedence; switch( dest->type ) { case DEBUGGER_EXPRESSION_TYPE_INTEGER: dest->types.integer = src->types.integer; break; case DEBUGGER_EXPRESSION_TYPE_REGISTER: dest->types.reg = src->types.reg; break; case DEBUGGER_EXPRESSION_TYPE_UNARYOP: dest->types.unaryop.operation = src->types.unaryop.operation; dest->types.unaryop.op = debugger_expression_copy( src->types.unaryop.op ); if( !dest->types.unaryop.op ) { free( dest ); return NULL; } break; case DEBUGGER_EXPRESSION_TYPE_BINARYOP: dest->types.binaryop.operation = src->types.binaryop.operation; dest->types.binaryop.op1 = debugger_expression_copy( src->types.binaryop.op1 ); if( !dest->types.binaryop.op1 ) { free( dest ); return NULL; } dest->types.binaryop.op2 = debugger_expression_copy( src->types.binaryop.op2 ); if( !dest->types.binaryop.op2 ) { debugger_expression_delete( dest->types.binaryop.op1 ); free( dest ); return NULL; } break; case DEBUGGER_EXPRESSION_TYPE_VARIABLE: dest->types.variable = strdup( src->types.variable ); if( !dest->types.variable ) { free( dest ); return NULL; } break; } return dest; }
/* Set the breakpoint's conditional expression */ int debugger_breakpoint_set_condition( size_t id, debugger_expression *condition ) { debugger_breakpoint *bp; bp = get_breakpoint_by_id( id ); if( !bp ) return 1; if( bp->condition ) debugger_expression_delete( bp->condition ); if( condition ) { bp->condition = debugger_expression_copy( condition ); if( !bp->condition ) return 1; } else { bp->condition = NULL; } return 0; }
static int breakpoint_add( debugger_breakpoint_type type, debugger_breakpoint_value value, size_t ignore, debugger_breakpoint_life life, debugger_expression *condition ) { debugger_breakpoint *bp; bp = malloc( sizeof( *bp ) ); if( !bp ) { ui_error( UI_ERROR_ERROR, "Out of memory at %s:%d", __FILE__, __LINE__ ); return 1; } bp->id = next_breakpoint_id++; bp->type = type; bp->value = value; bp->ignore = ignore; bp->life = life; if( condition ) { bp->condition = debugger_expression_copy( condition ); if( !bp->condition ) { free( bp ); return 1; } } else { bp->condition = NULL; } bp->commands = NULL; debugger_breakpoints = g_slist_append( debugger_breakpoints, bp ); if( debugger_mode == DEBUGGER_MODE_INACTIVE ) debugger_mode = DEBUGGER_MODE_ACTIVE; /* If this was a timed breakpoint, set an event to stop emulation at that point */ if( type == DEBUGGER_BREAKPOINT_TYPE_TIME ) { int error; error = event_add( value.time.tstates, debugger_breakpoint_event ); if( error ) return error; } return 0; }