/* This file is part of Mailfromd. Copyright (C) 2005-2008, 2010-2011, 2015-2016 Sergey Poznyakoff This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 3, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program. If not, see . */ #ifdef HAVE_CONFIG_H # include #endif #include #include #include "mailfromd.h" struct mf_stack { char *base; size_t tos; size_t elsize; size_t elcount; }; #define STACK_PTR(s, n) (void*)((s)->base + (n) * (s)->elsize) mf_stack_t mf_stack_create(size_t elsize, size_t count) { mf_stack_t stk = mu_alloc(sizeof *stk); stk->elsize = elsize; stk->base = NULL; if (!count) count = 64; stk->elcount = count; stk->base = mu_2nrealloc(stk->base, &stk->elcount, stk->elsize); stk->tos = 0; return stk; } void mf_stack_destroy(mf_stack_t *pstk) { free((*pstk)->base); free(*pstk); *pstk = NULL; } void mf_stack_push(mf_stack_t stk, void *item) { if (stk->tos == stk->elcount) stk->base = mu_2nrealloc(stk->base, &stk->elcount, stk->elsize); memcpy(STACK_PTR(stk, stk->tos), item, stk->elsize); stk->tos++; } int mf_stack_pop(mf_stack_t stk, void *ptr) { if (stk->tos == 0) return 1; --stk->tos; if (ptr) memcpy(ptr, STACK_PTR(stk, stk->tos), stk->elsize); return 0; } int mf_stack_peek(mf_stack_t stk, size_t n, void *ptr) { if (stk->tos == 0 || n + 1 > stk->tos) return 1; if (ptr) memcpy(ptr, STACK_PTR(stk, stk->tos - 1 - n), stk->elsize); return 0; } size_t mf_stack_count(mf_stack_t stk) { return stk->tos; } int mf_stack_enumerate_desc(mf_stack_t stk, mf_stack_enumerator fun, void *data) { size_t i; for (i = stk->tos; i > 0; i--) { int rc = fun(STACK_PTR(stk, i - 1), data); if (rc) return rc; } return 0; } int mf_stack_enumerate_asc(mf_stack_t stk, mf_stack_enumerator fun, void *data) { size_t i; for (i = 0; i < stk->tos; i++) { int rc = fun(STACK_PTR(stk, i), data); if (rc) return rc; } return 0; }