spacepaste

  1.  
  2. $ cat new.c
  3. #include <stdbool.h>
  4. #include <stdio.h>
  5. #include <stdlib.h>
  6. #include <string.h>
  7. #define pp(x) printf("%s = %p\n", #x, x);
  8. #define pi(x) printf("%s = %d\n", #x, x);
  9. #define pc(x) printf("%s = %c\n", #x, x);
  10. #define psize_t(x) printf("%s = %zu\n", #x, x);
  11. // A C program to demonstrate linked list based implementation of queue
  12. // A linked list (LL) node to store a queue entry
  13. int index_start = -1;
  14. int ref_start = 0;
  15. int global_indent = 0;
  16. #define node_init(t, i, r, nc, n) t->index = i; t->ref = r; t->next_count = nc; t->next = n; t->level = global_indent;
  17. #define STORE_NORMAL 1
  18. #define STORE_EMPTY 2
  19. #define NODE_TYPE_NORMAL 1
  20. #define NODE_TYPE_BRANCH_START 2
  21. #define NODE_TYPE_BRANCH_END 3
  22. #define NODE_TYPE_BRANCH_CHOICE_START 4
  23. #define NODE_TYPE_BRANCH_CHOICE_END 5
  24. #define POINTER_LIST_TYPE int
  25. POINTER_LIST_TYPE ** ptr_list = NULL;
  26. ssize_t ptr_list_size = 0;
  27. int last_ref = 0;
  28. int ptr_add(POINTER_LIST_TYPE * ptr) {
  29. if (!ptr) return -1;
  30. POINTER_LIST_TYPE ** pl;
  31. if (!ptr_list) {
  32. ptr_list = malloc(sizeof(ptr_list)*2);
  33. }
  34. else if (ptr_list) {
  35. ptr_list = realloc(ptr_list, sizeof(ptr_list)*(ptr_list_size+1));
  36. }
  37. ptr_list[ptr_list_size] = ptr;
  38. ptr_list_size++;
  39. ptr_list[ptr_list_size] = NULL;
  40. // psize_t(ptr_list_size);
  41. return 0;
  42. }
  43. int ptr_print(void) {
  44. if (!ptr_list) return -1;
  45. POINTER_LIST_TYPE ** pl;
  46. for (pl = ptr_list; *pl; pl++) pp(*pl);
  47. return 0;
  48. }
  49. int ptr_set(POINTER_LIST_TYPE data) {
  50. if (!ptr_list) return -1;
  51. POINTER_LIST_TYPE ** pl;
  52. for (pl = ptr_list; *pl; pl++) **pl = data;
  53. return 0;
  54. }
  55. int ptr_free(void) {
  56. if (!ptr_list) return -1;
  57. POINTER_LIST_TYPE ** pl;
  58. for (pl = ptr_list; *pl; pl++) *pl = NULL;
  59. free(ptr_list);
  60. ptr_list = NULL;
  61. ptr_list_size = 0;
  62. return 0;
  63. }
  64. struct QNode
  65. {
  66. int level;
  67. int index;
  68. int ref;
  69. int next_count;
  70. int type;
  71. struct QNode **next;
  72. };
  73. // The queue, front stores the front node of LL and rear stores ths
  74. // last node of LL
  75. struct Queue
  76. {
  77. struct QNode *front, *rear;
  78. };
  79. // A utility function to create a new linked list node.
  80. struct QNode* newNode(int type)
  81. {
  82. struct QNode *temp = (struct QNode*)malloc(sizeof(struct QNode));
  83. if (type == STORE_NORMAL) {
  84. node_init(temp, index_start++, ref_start++, 0, NULL);
  85. } else if (type == STORE_EMPTY) {
  86. node_init(temp, 0, 0, 0, NULL);
  87. }
  88. return temp;
  89. }
  90. // A utility function to create an empty queue
  91. struct Queue *createQueue()
  92. {
  93. struct Queue *q = (struct Queue*)malloc(sizeof(struct Queue));
  94. q->front = q->rear = NULL;
  95. return q;
  96. }
  97. void store_asm(struct Queue *q, int type)
  98. {
  99. // Create a new LL node
  100. int t = 0;
  101. if (type == NODE_TYPE_NORMAL) t = STORE_NORMAL;
  102. else if (
  103. type == NODE_TYPE_BRANCH_START
  104. ||
  105. type == NODE_TYPE_BRANCH_END
  106. ||
  107. type == NODE_TYPE_BRANCH_CHOICE_START
  108. ||
  109. type == NODE_TYPE_BRANCH_CHOICE_END
  110. ) t = STORE_EMPTY;
  111. struct QNode *temp = newNode(t);
  112. temp->type = type;
  113. // If queue is empty, then new node is front and rear both
  114. if (q->rear == NULL)
  115. {
  116. q->front = q->rear = temp;
  117. if (!q->rear->next) {
  118. q->rear->next_count = 1;
  119. q->rear->next = malloc(sizeof(struct QNode)*q->rear->next_count);
  120. } else {
  121. q->rear->next_count++;
  122. q->rear->next = realloc(q->rear->next, sizeof(struct QNode)*q->rear->next_count);
  123. }
  124. return;
  125. }
  126. if (type == NODE_TYPE_BRANCH_CHOICE_END) {
  127. // pp(&q->rear->ref)
  128. last_ref = q->rear->ref;
  129. ptr_add(&q->rear->ref);
  130. }
  131. else if(type == NODE_TYPE_BRANCH_END) {
  132. // pi(last_ref);
  133. ptr_set(last_ref);
  134. ptr_free();
  135. }
  136. // Add the new node at the end of queue and change rear
  137. q->rear->next[q->rear->next_count-1] = temp;
  138. q->rear = temp;
  139. if (!q->rear->next) {
  140. q->rear->next_count = 1;
  141. q->rear->next = malloc(sizeof(struct QNode)*q->rear->next_count);
  142. } else {
  143. q->rear->next_count++;
  144. q->rear->next = realloc(q->rear->next, sizeof(struct QNode)*q->rear->next_count);
  145. }
  146. }
  147. void add(struct Queue **q) {
  148. if (!(*q)) (*q) = createQueue();
  149. store_asm((*q), NODE_TYPE_NORMAL);
  150. }
  151. #define add_indent(indent) { int i = 0; for (; i < indent; i++) printf(" "); }
  152. struct Queue * list = NULL;
  153. void print(struct QNode * p, int indent) {
  154. int indentation = 0;
  155. while(p) {
  156. indentation = p->level;
  157. add_indent(indentation);
  158. if (p->type == NODE_TYPE_BRANCH_START) {
  159. add_indent(indentation);
  160. printf("branch start\n");
  161. }
  162. else if (p->type == NODE_TYPE_BRANCH_END) {
  163. add_indent(indentation);
  164. printf("branch end\n");
  165. }
  166. else if (p->type == NODE_TYPE_BRANCH_CHOICE_START) {
  167. add_indent(indentation);
  168. printf("branch choice start\n");
  169. }
  170. else if (p->type == NODE_TYPE_BRANCH_CHOICE_END) {
  171. add_indent(indentation);
  172. printf("branch choice end\n");
  173. }
  174. else if (p->type == NODE_TYPE_NORMAL) {
  175. add_indent(indentation);
  176. printf("%d -> %d\n", p->index, p->ref);
  177. if (p->next_count > 1) print(p->next[1], indent+1);
  178. }
  179. if (p->next) p = p->next[0];
  180. else p = NULL;
  181. }
  182. add_indent(indentation);
  183. puts("NULL");
  184. }
  185. void add_branch(struct Queue **q) {
  186. if (!(*q)) (*q) = createQueue();
  187. store_asm((*q), NODE_TYPE_BRANCH_START);
  188. global_indent++;
  189. }
  190. void end_branch(struct Queue **q) {
  191. global_indent--;
  192. if (!(*q)) (*q) = createQueue();
  193. store_asm((*q), NODE_TYPE_BRANCH_END);
  194. }
  195. void add_branch_choice(struct Queue **q) {
  196. if (!(*q)) (*q) = createQueue();
  197. store_asm((*q), NODE_TYPE_BRANCH_CHOICE_START);
  198. global_indent++;
  199. }
  200. void end_branch_choice(struct Queue **q) {
  201. global_indent--;
  202. if (!(*q)) (*q) = createQueue();
  203. store_asm((*q), NODE_TYPE_BRANCH_CHOICE_END);
  204. }
  205. int main(void) {
  206. index_start = 0;
  207. ref_start = 1;
  208. add(&list);
  209. add_branch(&list);
  210. add_branch_choice(&list);
  211. add(&list);
  212. add(&list);
  213. end_branch_choice(&list);
  214. add_branch_choice(&list);
  215. add(&list);
  216. add(&list);
  217. end_branch_choice(&list);
  218. end_branch(&list);
  219. add(&list);
  220. print(list->front, 0);
  221. ptr_print();
  222. return 0;
  223. }
  224. $ gcc new.c -o new
  225. $ ./new
  226. 0 -> 1
  227. branch start
  228. branch choice start
  229. 1 -> 2
  230. 2 -> 5
  231. branch choice end
  232. branch choice start
  233. 3 -> 4
  234. 4 -> 5
  235. branch choice end
  236. branch end
  237. 5 -> 6
  238. NULL
  239.