The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo03.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo03.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 10:09:46 2015
10  * Version : 0.51
11  * ---
12  * Description: A demo of stack/queue ADT usage - in LevAWC
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 130122 Created this file - the first time..
17  * 130123 Completed the code - and debugged/tested it as well..
18  * 150121 Made this demo3.c menu-driven
19  * 150220 Moved some utility functions from here - to file ../utils.c
20  * 150220 Source ready for version 0.5!
21  * 150317 Source ready for version 0.51
22  *
23  */
24 
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <time.h>
28 #include <assert.h>
29 #include "stack.h"
30 #include "queue.h"
31 #include "utils.h"
32 
33 #define NR_OF_ITEMS 8
34 
35 #ifndef OK
36 #define OK 0
37 #endif
38 
39 #ifndef TRUE
40 #define TRUE 1
41 #endif
42 
43 #ifndef FALSE
44 #define FALSE 0
45 #endif
46 
47 /* Some string macros for the main menu... */
48 #define MAIN_MENU_ROW "--- QUEUE/STACK DEMO ---\nMENU: 0=Exit 1=Enqueue 2=Dequeue 3=Push 4=Pop 5=Dequeue/Push 6=Print\nSelection "
49 
50 /* FUNCTION-DECLARATIONS */
51 /* Application-specific callbacks */
52 void my_destroy(void *data);
53 int my_chkch(int ch);
54 void print(const void *data);
55 
56 /* Functions handling menu selections */
57 void enqueue_node(Queue que);
58 void dequeue_node(Queue que);
59 void push_node(Stack stk);
60 void pop_node(Stack stk);
61 void print_queue_stack(Queue que, Stack stk);
62 void dequeue_push_node(Queue que, Stack stk);
63 void final_status(Queue que, Stack stk);
64 
65 /* Misc. application functions.. */
66 void enqueue_push_nodes(Queue que, Stack stk, int nr_of_ele);
67 /* END-OF-FUNCTION-DECLARATIONS */
68 
69 /* FUNCTION-DEFINITIONS - that is, the rest of the program */
70 /* --- Function: void my_destroy(void *data) --- */
71 void my_destroy(void *data)
72 {
73  free(data);
74 }
75 
76 /* --- Function: int my_chkch(int ch) --- */
77 int my_chkch(int ch)
78 {
79  return strchr("YyNn", ch) ? 1 : 0;
80 }
81 
82 /* --- Function: void print(const void *data) --- */
83 void print(const void *data)
84 {
85  printf(" %02d", *(int *)data);
86 }
87 
88 /* --- Function: void queue_nodess(Queue que, Stack stk, int nr_of_ele) --- */
89 void enqueue_push_nodes(Queue que, Stack stk, int nr_of_ele)
90 {
91  int i=0, *pi, retval;
92 
93  my_clearscrn();
94  printf("--- CREATING QUEUE AND STACK (%d nodes each), RANDOM INTEGER DATA ---\n", NR_OF_ITEMS);
95 
96  do
97  {
98  /* Create dyn. memory, store random nr - and enqueue... */
99  pi = (int *)malloc(sizeof(int));
100  MALCHK(pi);
101 
102  *pi = rand_int(1,50);
103 
104  retval = QUEUEenqueue(que, pi);
105  assert(retval == OK);
106 
107  /* Create dyn. memory, store random nr - and push... */
108  pi = (int *)malloc(sizeof(int));
109  MALCHK(pi);
110 
111  *pi = rand_int(1,50);
112 
113  retval = STACKpush(stk, pi);
114  assert(retval == OK);
115 
116  } while (++i < nr_of_ele);
117 
118  printf("\nCurrent queue and stack status: ");
119  printf("\nQueue(%d nodes): ", QUEUEsize(que));
120  SLISTtraverse(que, print, SLIST_FWD);
121  printf("\nStack(%d nodes): ", STACKsize(stk));
122  SLISTtraverse(stk, print, SLIST_FWD);
123  prompt_and_pause("\n\n");
124 }
125 
126 /* --- Function: void enqueue_node(Queue que) --- */
127 void enqueue_node(Queue que)
128 {
129  int tmp, *pi;
130  char mess[BUFSIZ];
131 
132  do
133  {
134  my_clearscrn();
135  printf("--- ENQUEUE NODE TO QUEUE ---\n");
136  printf("\nCurrent queue status(%d nodes): ", QUEUEsize(que));
137  SLISTtraverse(que, print, SLIST_FWD);
138 
139  tmp = read_int("\nEnter integer data of node to be enqueued (-1=Quit): ", 0, 0);
140 
141  if (tmp == -1)
142  break;
143 
144  pi = (int *)malloc(sizeof(int));
145  MALCHK(pi);
146 
147  *pi = tmp;
148 
149  if ((QUEUEenqueue(que, pi)) != OK)
150  {
151  printf("\nFatal error enqueing data - exiting...!");
152  QUEUEdestroy(que);
153  exit(-1);
154  }
155  else
156  {
157  sprintf(mess, "Node %d will be enqueued!", *pi);
158  prompt_and_pause(mess);
159  }
160  } while (TRUE);
161 }
162 
163 /* --- Function: void dequeue_node(Queue que) --- */
164 void dequeue_node(Queue que)
165 {
166  int tmp, *pi, *ptmp;
167  char mess[BUFSIZ], ans;
168 
169  /* Initialize 'tmp'... */
170  tmp = 0;
171 
172  do
173  {
174  if (tmp == -1)
175  break;
176 
177  my_clearscrn();
178  printf("--- DEQUEUE NODE FROM QUEUE ---\n");
179  printf("\nCurrent queue status(%d nodes): ", QUEUEsize(que));
180  SLISTtraverse(que, print, SLIST_FWD);
181 
182  ptmp = (int *)QUEUEpeek(que);
183 
184  if (ptmp == NULL)
185  {
186  prompt_and_pause("\n\nQueue is EMPTY - nothing to do..!");
187  tmp = -1;
188  }
189  else
190  {
191  sprintf(mess, "\nAbout to dequeue node %d.. - Continue? (y/n): ", *ptmp);
192  ans = read_char(mess, 0, 0, my_chkch);
193 
194  if (ans == 'y' || ans == 'Y')
195  {
196  if ((QUEUEdequeue(que, (void **)&pi)) != OK)
197  {
198  printf("\nFatal error dequeing data - exiting...!");
199  QUEUEdestroy(que);
200  exit(-1);
201  }
202  else
203  {
204  sprintf(mess, "Node %d will be dequeued!", *pi);
205  prompt_and_pause(mess);
206  my_destroy(pi);
207  }
208  }
209  else
210  tmp = -1;
211  }
212  } while (TRUE);
213 }
214 
215 /* --- Function: void push_node(Stack stk) --- */
216 void push_node(Stack stk)
217 {
218  int tmp, *pi;
219  char mess[BUFSIZ];
220 
221  do
222  {
223  my_clearscrn();
224  printf("--- PUSH NODE ON STACK ---\n");
225  printf("\nCurrent stack status(%d nodes): ", STACKsize(stk));
226  SLISTtraverse(stk, print, SLIST_FWD);
227 
228  tmp = read_int("\nEnter integer data of node to be pushed (-1=Quit): ", 0, 0);
229 
230  if (tmp == -1)
231  break;
232 
233  pi = (int *)malloc(sizeof(int));
234  MALCHK(pi);
235 
236  *pi = tmp;
237 
238  if ((STACKpush(stk, pi)) != OK)
239  {
240  printf("\nFatal error pushing data - exiting...!");
241  STACKdestroy(stk);
242  exit(-1);
243  }
244  else
245  {
246  sprintf(mess, "Node %d will be pushed on stack!", *pi);
247  prompt_and_pause(mess);
248  }
249  } while (TRUE);
250 }
251 
252 /* --- Function: void pop_node(Stack stk) --- */
253 void pop_node(Stack stk)
254 {
255  int tmp, *pi, *ptmp;
256  char mess[BUFSIZ], ans;
257 
258  /* Initialize 'tmp'... */
259  tmp = 0;
260 
261  do
262  {
263  if (tmp == -1)
264  break;
265 
266  my_clearscrn();
267  printf("--- POP NODE FROM STACK ---\n");
268  printf("\nCurrent stack status(%d nodes): ", STACKsize(stk));
269  SLISTtraverse(stk, print, SLIST_FWD);
270 
271  ptmp = (int *)STACKpeek(stk);
272 
273  if (ptmp == NULL)
274  {
275  prompt_and_pause("\n\nStack is EMPTY - nothing to do..!");
276  tmp = -1;
277  }
278  else
279  {
280  sprintf(mess, "\nAbout to pop node %d.. - Continue? (y/n): ", *ptmp);
281  ans = read_char(mess, 0, 0, my_chkch);
282 
283  if (ans == 'y' || ans == 'Y')
284  {
285  if ((STACKpop(stk, (void **)&pi)) != OK)
286  {
287  printf("\nFatal error popping data - exiting...!");
288  STACKdestroy(stk);
289  exit(-1);
290  }
291  else
292  {
293  sprintf(mess, "Node %d will be popped!", *pi);
294  prompt_and_pause(mess);
295  my_destroy(pi);
296  }
297  }
298  else
299  tmp = -1;
300  }
301  } while (TRUE);
302 }
303 
304 /* --- Function: void dequeue_push_node(Queue que, Stack stk) --- */
305 void dequeue_push_node(Queue que, Stack stk)
306 {
307  int tmp, *pi, *ptmp;
308  char mess[BUFSIZ], ans;
309 
310  /* Initialize 'tmp'... */
311  tmp = 0;
312 
313  do
314  {
315  if (tmp == -1)
316  break;
317 
318  my_clearscrn();
319  printf("--- DEQUEUE NODE FROM QUEUE AND PUSH ON STACK ---\n");
320  printf("\nCurrent queue/stack status: ");
321  printf("\nQueue: ");
322  SLISTtraverse(que, print, SLIST_FWD);
323  printf(" (%d nodes)", QUEUEsize(que));
324  printf("\nStack: ");
325  SLISTtraverse(stk, print, SLIST_FWD);
326  printf(" (%d nodes)", STACKsize(stk));
327 
328  ptmp = (int *)QUEUEpeek(que);
329 
330  if (ptmp == NULL)
331  {
332  prompt_and_pause("\n\nQueue is EMPTY - nothing to do..!");
333  tmp = -1;
334  }
335  else
336  {
337  sprintf(mess, "\nAbout to dequeue node %d - and push it on stack.. - Continue? (y/n): ", *ptmp);
338  ans = read_char(mess, 0, 0, my_chkch);
339 
340  if (ans == 'y' || ans == 'Y')
341  {
342  if ((QUEUEdequeue(que, (void **)&pi)) != OK)
343  {
344  printf("\nFatal error dequeing data - exiting...!");
345  QUEUEdestroy(que);
346  exit(-1);
347  }
348  else
349  {
350  if (STACKpush(stk, pi) != OK)
351  {
352  printf("\nFatal error pushing data - exiting...!");
353  STACKdestroy(stk);
354  exit(-1);
355  }
356 
357  sprintf(mess, "Node %d will be dequeued - and pushed on stack..!", *pi);
358  prompt_and_pause(mess);
359  }
360  }
361  else
362  tmp = -1;
363  }
364  } while (TRUE);
365 }
366 
367 /* --- Function: void print_queue_stack(Queue que, Stack stk) --- */
368 void print_queue_stack(Queue que, Stack stk)
369 {
370  my_clearscrn();
371  printf("--- PRINT QUEUE AND STACK ---\n");
372  printf("\nCurrent contents: ");
373  printf("\nQueue: ");
374  SLISTtraverse(que, print, SLIST_FWD);
375  printf(" (%d nodes)", QUEUEsize(que));
376  printf("\nStack: ");
377  SLISTtraverse(stk, print, SLIST_FWD);
378  printf(" (%d nodes)", STACKsize(stk));
379  prompt_and_pause("\n\n");
380 }
381 
382 /* --- Function: void final_status(Queue que, Stack stk) --- */
383 void final_status(Queue que, Stack stk)
384 {
385  /* Final list status... */
386  my_clearscrn();
387  printf("--- FINAL STATUS ---\n");
388  printf("\nFinal list contents: ");
389  printf("\nQueue: ");
390  SLISTtraverse(que, print, SLIST_FWD);
391  printf(" (%d nodes)", QUEUEsize(que));
392  printf("\nStack: ");
393  SLISTtraverse(stk, print, SLIST_FWD);
394  printf(" (%d nodes)", STACKsize(stk));
395 }
396 
397 int main(void)
398 {
399  /* Declare YOUR variables here ! */
400  Stack mystack;
401  Queue myqueue;
402  int menu_choice;
403 
404  srand((unsigned int)time(NULL));
405 
406  if ((myqueue = QUEUEinit(my_destroy)) == NULL) /* Create new queue... */
407  {
408  printf("\nFatal error - bailing out...!");
409  QUEUEdestroy(myqueue);
410  exit(-1);
411  }
412 
413  if ((mystack = STACKinit(my_destroy)) == NULL) /* Create new stack... */
414  {
415  printf("\nFatal error - bailing out...!");
416  STACKdestroy(mystack);
417  exit(-1);
418  }
419 
420  /* Create and initialize queue and stack... */
421  enqueue_push_nodes(myqueue, mystack, NR_OF_ITEMS);
422 
423  do
424  {
425  menu_choice = menu(MAIN_MENU_ROW, 0, 6);
426 
427  switch (menu_choice)
428  {
429  case 1:
430  enqueue_node(myqueue);
431  break;
432  case 2:
433  dequeue_node(myqueue);
434  break;
435  case 3:
436  push_node(mystack);
437  break;
438  case 4:
439  pop_node(mystack);
440  break;
441  case 5:
442  dequeue_push_node(myqueue, mystack);
443  break;
444  case 6:
445  print_queue_stack(myqueue, mystack);
446  break;
447  default:
448  final_status(myqueue, mystack);
449  break;
450  }
451  }
452  while (menu_choice);
453 
454  prompt_and_pause("\n\nLet's tidy up (destroy queue/stack)..- Bye!");
455 
456  STACKdestroy(mystack);
457  QUEUEdestroy(myqueue);
458 
459  return 0;
460 }