Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- typedef void(*res_destruct_t)(void*);
- typedef struct scope_node { void *res; res_destruct_t destruct; struct scope_node *prev, *next; } scope_node_t;
- typedef struct { scope_node_t *beg, *end; } scope_t;
- void scope_init(scope_t *stk)
- {
- stk->beg = stk->end = NULL;
- }
- void* scope_push(scope_t *stk, void *res, res_destruct_t destructor)
- {
- scope_node_t *node;
- node = (scope_node_t *) malloc(sizeof(scope_node_t));
- node->next = NULL;
- node->prev = stk->end;
- node->res = res;
- node->destruct = destructor;
- if (!stk->beg)
- stk->beg = node;
- else
- stk->end->next = node;
- stk->end = node;
- return res;
- }
- void scope_pop(scope_t *stk)
- {
- scope_node_t *last;
- last = stk->end;
- stk->end = last->prev;
- stk->end->next = NULL;
- free(last);
- }
- void scope_destruct_last(scope_t *stk)
- {
- scope_node_t *last;
- last = stk->end;
- last->destruct(last->res);
- stk->end = last->prev;
- stk->end->next = NULL;
- free(last);
- }
- void scope_destruct_all(scope_t *stk)
- {
- scope_node_t *node, *next;
- for (node = stk->beg; node != NULL; node = next) {
- node->destruct(node->res);
- next = node->next;
- free(node);
- }
- stk->beg = stk->end = NULL;
- }
- #define SCOPE_PUSH(p, r, d) \
- scope_push(&p, (void*)(r), (res_destruct_t)(d))
- #define ERROR(p, ret) \
- do { scope_pop(&p); scope_destruct_all(&p); return (ret); } while (0)
- #define RETURN(p, ret) \
- do { scope_destruct_all(&p); return (ret); } while (0)
- int main()
- {
- scope_t stk;
- char *buffer;
- FILE *file;
- size_t s;
- scope_init(&stk); /* This line is a pice of shit. Can I avoid it? */
- buffer = SCOPE_PUSH(stk, malloc(1024), free);
- if (!buffer) {
- fputs("Cannot allocate memory\n", stderr);
- ERROR(stk, EXIT_FAILURE);
- }
- file = SCOPE_PUSH(stk, fopen("main.c", "r"), fclose);
- if (!file) {
- fputs("Cannot open an file\n", stderr);
- ERROR(stk, EXIT_FAILURE);
- }
- while (!feof(file)) {
- s = fread(buffer, 1, 1024, file);
- fwrite(buffer, 1, s, stdout);
- }
- RETURN(stk, EXIT_SUCCESS);
- }
Add Comment
Please, Sign In to add comment