Added tests for the stack and made them pass.
* Make 'empty(stack)' more robust * Only try to 'push(stack, card)' if card != NULL * Added message explaining why 'pop(stack)' needs to create a new stack object when popping a stack's last element * 'move_card(stack, stack)' now checks if the origin pops something before trying to 'push(stack)' to destination. This prevents dereferencing a possible NULL pointer.
This commit is contained in:
37
lib/stack.c
37
lib/stack.c
@@ -38,7 +38,10 @@ void delete_stack(struct stack *stack) {
|
||||
}
|
||||
|
||||
bool empty(struct stack *stack) {
|
||||
return(stack->card->value == NO_VALUE);
|
||||
return(stack->card->value == NO_VALUE &&
|
||||
stack->card->suit == NO_SUIT &&
|
||||
stack->card->face == NO_FACE &&
|
||||
!stack->next);
|
||||
}
|
||||
|
||||
int length(struct stack *stack) {
|
||||
@@ -59,29 +62,32 @@ int length(struct stack *stack) {
|
||||
void push(struct stack **stack, struct card *card) {
|
||||
struct stack *new_stack = NULL;
|
||||
|
||||
if (empty(*stack)) {
|
||||
(*stack)->card = card;
|
||||
} else {
|
||||
allocate_stack(&new_stack);
|
||||
new_stack->card = card;
|
||||
new_stack->next = (*stack);
|
||||
*stack = new_stack;
|
||||
if (card) {
|
||||
if (empty(*stack)) {
|
||||
(*stack)->card = card;
|
||||
} else {
|
||||
allocate_stack(&new_stack);
|
||||
new_stack->card = card;
|
||||
new_stack->next = (*stack);
|
||||
*stack = new_stack;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* FIXME: hack hack hack to get the old coordinates after clearing the structure */
|
||||
struct stack *pop(struct stack **stack) {
|
||||
struct stack *popped_entry = NULL;
|
||||
|
||||
if(!empty(*stack)) {
|
||||
popped_entry = *stack;
|
||||
/* As what's considered an empty stack is an allocated and initialized
|
||||
* stack structure, we make sure pop doesn't make '*stack' point to NULL
|
||||
* when popping a stack with only 1 element. */
|
||||
if (length(*stack) == 1) {
|
||||
int start_y, start_x;
|
||||
start_y = (*stack)->card->frame->start_y;
|
||||
start_x = (*stack)->card->frame->start_x;
|
||||
allocate_stack(stack);
|
||||
initialize_stack(*stack);
|
||||
set_frame((*stack)->card->frame, start_y, start_x);
|
||||
set_frame((*stack)->card->frame,
|
||||
(*stack)->card->frame->start_y,
|
||||
(*stack)->card->frame->start_x);
|
||||
} else {
|
||||
*stack = (*stack)->next;
|
||||
}
|
||||
@@ -99,8 +105,9 @@ void move_card(struct stack **origin, struct stack **destination) {
|
||||
if (!empty(*destination) && maneuvre_stack(*destination)) {
|
||||
(*origin)->card->frame->start_y++;
|
||||
}
|
||||
stack = pop(origin);
|
||||
push(destination, stack->card);
|
||||
if ((stack = pop(origin))) {
|
||||
push(destination, stack->card);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user