Guest User

Untitled

a guest
Jul 16th, 2018
87
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.00 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3.  
  4. typedef void(*res_destruct_t)(void*);
  5. typedef struct scope_node { void *res; res_destruct_t destruct; struct scope_node *prev, *next; } scope_node_t;
  6. typedef struct { scope_node_t *beg, *end; } scope_t;
  7.  
  8. void scope_init(scope_t *stk)
  9. {
  10. stk->beg = stk->end = NULL;
  11. }
  12.  
  13. void* scope_push(scope_t *stk, void *res, res_destruct_t destructor)
  14. {
  15. scope_node_t *node;
  16. node = (scope_node_t *) malloc(sizeof(scope_node_t));
  17. node->next = NULL;
  18. node->prev = stk->end;
  19. node->res = res;
  20. node->destruct = destructor;
  21.  
  22. if (!stk->beg)
  23. stk->beg = node;
  24. else
  25. stk->end->next = node;
  26.  
  27. stk->end = node;
  28.  
  29. return res;
  30. }
  31.  
  32. void scope_pop(scope_t *stk)
  33. {
  34. scope_node_t *last;
  35. last = stk->end;
  36. stk->end = last->prev;
  37. stk->end->next = NULL;
  38. free(last);
  39. }
  40.  
  41. void scope_destruct_last(scope_t *stk)
  42. {
  43. scope_node_t *last;
  44. last = stk->end;
  45. last->destruct(last->res);
  46. stk->end = last->prev;
  47. stk->end->next = NULL;
  48. free(last);
  49. }
  50.  
  51. void scope_destruct_all(scope_t *stk)
  52. {
  53. scope_node_t *node, *next;
  54. for (node = stk->beg; node != NULL; node = next) {
  55. node->destruct(node->res);
  56. next = node->next;
  57. free(node);
  58. }
  59.  
  60. stk->beg = stk->end = NULL;
  61. }
  62.  
  63. #define SCOPE_PUSH(p, r, d) \
  64. scope_push(&p, (void*)(r), (res_destruct_t)(d))
  65.  
  66. #define ERROR(p, ret) \
  67. do { scope_pop(&p); scope_destruct_all(&p); return (ret); } while (0)
  68.  
  69. #define RETURN(p, ret) \
  70. do { scope_destruct_all(&p); return (ret); } while (0)
  71.  
  72. int main()
  73. {
  74. scope_t stk;
  75. char *buffer;
  76. FILE *file;
  77. size_t s;
  78.  
  79. scope_init(&stk); /* This line is a pice of shit. Can I avoid it? */
  80.  
  81. buffer = SCOPE_PUSH(stk, malloc(1024), free);
  82. if (!buffer) {
  83. fputs("Cannot allocate memory\n", stderr);
  84. ERROR(stk, EXIT_FAILURE);
  85. }
  86.  
  87. file = SCOPE_PUSH(stk, fopen("main.c", "r"), fclose);
  88. if (!file) {
  89. fputs("Cannot open an file\n", stderr);
  90. ERROR(stk, EXIT_FAILURE);
  91. }
  92.  
  93. while (!feof(file)) {
  94. s = fread(buffer, 1, 1024, file);
  95. fwrite(buffer, 1, s, stdout);
  96. }
  97.  
  98. RETURN(stk, EXIT_SUCCESS);
  99. }
Add Comment
Please, Sign In to add comment