Name: Anonymous 2011-12-19 12:05
Does this qualify for a template?
utility_stack.h
Example usage:
utility_stack.h
#ifndef __UTILITY_STACK_H
#define __UTILITY_STACK_H
#include <stddef.h>
#include <stdlib.h>
#define UTILITY_STACK_RESIZE_FACTOR (0.70)
#define utility_stack(type) \
struct { \
type * base; \
type * read; \
type * end; \
}
#define utility_stack_init(stack) \
({ \
typeof(stack) __s = (stack); \
\
__s->base = NULL; \
__s->read = __s->base; \
__s->end = __s->base + 0; \
})
#define utility_stack_clear(stack) \
({ \
typeof(stack) __s = (stack); \
\
free(__s->base); \
})
#define utility_stack_push(stack, element) \
({ \
typeof(stack) __s = (stack); \
typeof(element) __e = (element); \
\
if (__s->read == __s->end) { \
ptrdiff_t __read_offset = (__s->read - __s->base); \
ptrdiff_t __size = (__s->end - __s->base); \
\
__s->base = realloc(__s->base, \
((size_t) \
((UTILITY_STACK_RESIZE_FACTOR + 1) * \
__size) + 1) * \
sizeof(*__s->base)); \
\
__s->read = __s->base + __read_offset; \
__s->end = __s->base + \
(size_t) ((UTILITY_STACK_RESIZE_FACTOR + 1) * \
__size) + 1; \
} \
\
*__s->read++ = __e; \
})
#define utility_stack_pop(stack) \
({ \
typeof(stack) __s = (stack); \
\
__s->read == __s->base ? \
(typeof(*__s->read)) NULL : \
*--__s->read; \
})
#define utility_stack_size(stack) \
({ \
typeof(stack) __s = (stack); \
\
(size_t) (__s->read - __s->base); \
})
#define utility_stack_contains(stack, candidate, eq) \
({ \
int __in = 0; \
\
typeof(stack) __s = (stack); \
typeof(candidate) __c = (candidate); \
typeof(__s->read) __r = __s->read; \
\
while (__s->base < __r) \
if (eq(__c, *--__r)) { \
__in = 1; \
break; \
} \
\
__in; \
})
#endif /* __UTILITY_STACK_H */Example usage:
#include <stdio.h>
#include <string.h>
#include "utility_stack.h"
#define str_eq(a, b) (strcmp(a, b) == 0)
int main (int argc, char ** argv) {
utility_stack(char *) s;
utility_stack_init(&s);
while (--argc)
utility_stack_push(&s, *++argv);
if (utility_stack_contains(&s, "/prog/", str_eq))
puts("/prog/ found on stack!");
while (utility_stack_size(&s))
printf("%s\n", utility_stack_pop(&s));
utility_stack_clear(&s);
return 0;
}