Blame stack.c

Packit 400c17
/*
Packit 400c17
	Copyright(C) 2016, Red Hat, Inc., Stanislav Kozina
Packit 400c17
Packit 400c17
	This program is free software: you can redistribute it and/or modify
Packit 400c17
	it under the terms of the GNU General Public License as published by
Packit 400c17
	the Free Software Foundation, either version 3 of the License, or
Packit 400c17
	(at your option) any later version.
Packit 400c17
Packit 400c17
	This program is distributed in the hope that it will be useful,
Packit 400c17
	but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 400c17
	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
Packit 400c17
	GNU General Public License for more details.
Packit 400c17
Packit 400c17
	You should have received a copy of the GNU General Public License
Packit 400c17
	along with this program.  If not, see <http://www.gnu.org/licenses/>.
Packit 400c17
*/
Packit 400c17
Packit 400c17
/*
Packit 400c17
 * A trivial stack implementation.
Packit 400c17
 */
Packit 400c17
Packit 400c17
#include <stdio.h>
Packit 400c17
#include <stdlib.h>
Packit 400c17
#include <stdbool.h>
Packit 400c17
#include <string.h>
Packit 400c17
Packit 400c17
#include "utils.h"
Packit 400c17
#include "stack.h"
Packit 400c17
Packit 400c17
#define	INIT_CAPACITY	10
Packit 400c17
Packit 400c17
stack_t *stack_init(void)
Packit 400c17
{
Packit 400c17
	stack_t *st = safe_zmalloc(sizeof(*st));
Packit 400c17
Packit 400c17
	st->st_capacity = INIT_CAPACITY;
Packit 400c17
	st->st_count = 0;
Packit 400c17
	st->st_data = safe_zmalloc(st->st_capacity * sizeof(*st->st_data));
Packit 400c17
Packit 400c17
	return st;
Packit 400c17
}
Packit 400c17
Packit 400c17
void stack_destroy(stack_t *st)
Packit 400c17
{
Packit 400c17
	if (st->st_count > 0)
Packit 400c17
		fail("Stack not empty!\n");
Packit 400c17
Packit 400c17
	free(st->st_data);
Packit 400c17
	(void) memset(st, 0, sizeof(*st));
Packit 400c17
	free(st);
Packit 400c17
}
Packit 400c17
Packit 400c17
void stack_push(stack_t *st, void *data)
Packit 400c17
{
Packit 400c17
	if (st->st_count == st->st_capacity) {
Packit 400c17
		st->st_capacity *= 2;
Packit 400c17
		st->st_data = realloc(st->st_data,
Packit 400c17
		    st->st_capacity * sizeof(*st->st_data));
Packit 400c17
	}
Packit 400c17
Packit 400c17
	st->st_data[st->st_count] = data;
Packit 400c17
	st->st_count++;
Packit 400c17
}
Packit 400c17
Packit 400c17
void *stack_pop(stack_t *st)
Packit 400c17
{
Packit 400c17
	if (st->st_count == 0)
Packit 400c17
		return NULL;
Packit 400c17
Packit 400c17
	st->st_count--;
Packit 400c17
	return st->st_data[st->st_count];
Packit 400c17
}
Packit 400c17
Packit 400c17
void *stack_head(stack_t *st)
Packit 400c17
{
Packit 400c17
	if (st->st_count == 0)
Packit 400c17
		return NULL;
Packit 400c17
Packit 400c17
	return st->st_data[st->st_count-1];
Packit 400c17
}
Packit 400c17
Packit 400c17
void walk_stack(stack_t *st, void (*cb)(void *, void *), void *arg)
Packit 400c17
{
Packit 400c17
	unsigned int i;
Packit 400c17
Packit 400c17
	for (i = 0; i < st->st_count; i++)
Packit 400c17
		cb(st->st_data[i], arg);
Packit 400c17
}
Packit 400c17
Packit 400c17
void walk_stack_backward(stack_t *st, void (*cb)(void *, void *), void *arg)
Packit 400c17
{
Packit 400c17
	unsigned int i;
Packit 400c17
Packit 400c17
	for (i = st->st_count; i > 0; i--)
Packit 400c17
		cb(st->st_data[i - 1], arg);
Packit 400c17
}