The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo09.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo09.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 12:02:43 2015
10  * Version : 0.51
11  * ---
12  * Description: A usage demo program - showing/testing the Set ADT
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 150127 Created this program the first time - and made it menu-driven..
17  * 150220 Moved some utility functions from here - to file ../utils.c
18  * 150220 This source ready for version 0.5!
19  * 150318 This source ready for version 0.51
20  *
21  */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include "set.h"
27 #include "utils.h"
28 
29 #ifndef OK
30 #define OK 0
31 #endif
32 
33 #ifndef TRUE
34 #define TRUE 1
35 #endif
36 
37 #ifndef FALSE
38 #define FALSE 0
39 #endif
40 
41 #define NR_OF_ITEMS 10
42 
43 /* Some string macros for the main menu... */
44 #define MAIN_MENU_ROW "--- SET DEMO ---\nMENU: 0=Exit 1=Set1_Add 2=Set2_Add 3=Set1_Rem 4=Set2_Rem 5=Print\nSelection "
45 
46 /* FUNCTION-DECLARATIONS */
47 /* Application-specific callbacks */
48 void my_destroy(void *data);
49 void print(const void *data);
50 int my_cmp(const void *key1, const void *key2);
51 int my_match(const void *k1, const void *k2);
52 
53 /* Functions handling menu selections */
54 void ins_node(Set set);
55 void rem_node(Set set);
56 void print_sets(Set set1, Set set2);
57 void print_union_diff_intersec(Set s1, Set s2);
58 void final_status(Set set1, Set set2);
59 
60 /* Misc. application functions.. */
61 void create_random_nodes(Set set, int nr_of_nodes);
62 /* END-OF-FUNCTION-DECLARATIONS */
63 
64 /* FUNCTION-DEFINITIONS - the rest of the program */
65 /* --- Function: void my_destroy(void *data) --- */
66 void my_destroy(void *data)
67 {
68  free(data);
69 }
70 
71 /* --- Function: void print(const void *data) --- */
72 void print(const void *data)
73 {
74  printf(" %02d", *(int *)data);
75 }
76 
77 /* --- Function: int my_cmp(const int *key1, const int *key2) --- */
78 int my_cmp(const void *key1, const void *key2)
79 {
80  return (*(int *)key1 - *(int *)key2);
81 }
82 
83 /* --- Function: int my_match(const void *k1, const void *k2) --- */
84 int my_match(const void *k1, const void *k2)
85 {
86  return *(int *)k1 == *(int *)k2;
87 }
88 
89 /* --- void add_random_nodes(Set set, int nr_of_nodes) --- */
90 void create_random_nodes(Set set, int nr_of_nodes)
91 {
92  int i=0, *pi, retval, dupctr=0;
93 
94  do
95  {
96  pi = (int *)malloc(sizeof(int));
97  MALCHK(pi);
98 
99  *pi = rand_int(1,50);
100 
101  if ((retval = SETinsert(set, pi)) != OK) /* Insertion failed... */
102  {
103  if (retval == 1) /* Duplicate key value.. */
104  {
105  dupctr++;
106  my_destroy(pi); /* Free node - since duplicate.. */
107  }
108  else
109  {
110  prompt_and_pause("Fatal error - bailing out..!\n");
111  SETdestroy(set);
112  exit(-1);
113  }
114  }
115  else
116  i++; /* Insertion successful! */
117 
118  } while (i < nr_of_nodes);
119 }
120 
121 /* --- Function: void ins_node(Set set) --- */
122 void ins_node(Set set)
123 {
124  int tmp, *pi, retval;
125  char mess[BUFSIZ];
126 
127  do
128  {
129  my_clearscrn();
130  printf("--- ADD NODE TO SET ---\n");
131  printf("\nCurrent set status(%d nodes): ", SETsize(set));
132  SETtraverse(set, print, SET_FWD);
133 
134  tmp = read_int("\nEnter nodedata for node to be inserted (-1=Quit): ", 0, 0);
135 
136  if (tmp == -1)
137  break;
138 
139  pi = (int *)malloc(sizeof(int));
140  MALCHK(pi);
141 
142  *pi = tmp;
143 
144  if ((retval = SETinsert(set, pi)) != OK) /* Insertion failed... */
145  {
146  if (retval == 1) /* Duplicate key value.. */
147  {
148  sprintf(mess, "Error: Duplicate - node %d already present..!", *pi);
149  prompt_and_pause(mess);
150  my_destroy(pi); /* Free node - since being duplicate.. */
151  }
152  else
153  {
154  if (retval == -2)
155  {
156  printf("\nMatch-callback is missing... - bailing out!");
157  prompt_and_pause(mess);
158  }
159  else
160  {
161  prompt_and_pause("Fatal error - bailing out..:!");
162  }
163  my_destroy(pi);
164  SETdestroy(set);
165  exit(-1); /* Bail out - since serious error.. */
166  }
167  }
168  else
169  {
170  sprintf(mess, "Node %d will be inserted..", *(int *)pi);
171  prompt_and_pause(mess);
172  }
173  } while (TRUE);
174 }
175 
176 /* --- Function: void rem_node(Set set) --- */
177 void rem_node(Set set)
178 {
179  int tmp, *pi, retval;
180  char mess[BUFSIZ];
181 
182  do
183  {
184  my_clearscrn();
185  printf("--- REMOVE NODE FROM SET ---\n");
186  printf("\nCurrent set status(%d nodes): ", SETsize(set));
187  SETtraverse(set, print, SET_FWD);
188 
189  tmp = read_int("\nEnter (key)data for node to be removed (-1=Quit): ", 0, 0);
190 
191  if (tmp == -1)
192  break;
193 
194  /* Remove node - and free memory */
195  pi = &tmp;
196 
197  if ((retval = SETremove(set, (void **)&pi)) != OK)
198  {
199  if (retval == 1)
200  {
201  sprintf(mess, "Error: Node %d not found..!", *(int *)pi);
202  prompt_and_pause(mess);
203  }
204  else
205  {
206  if (retval == -2)
207  printf("\nMatch-callback is missing... - bailing out!");
208  else
209  printf("\nFatal error... - bailing out!");
210  SETdestroy(set);
211  exit(retval);
212  }
213  }
214  else
215  {
216  /* Removal succesful - notify user.. */
217  sprintf(mess, "Node %d will be removed..!", *(int *)pi);
218  prompt_and_pause(mess);
219  /* Free node - after being removed from set.. */
220  my_destroy(pi);
221  }
222 
223  } while (TRUE);
224 }
225 
226 /* --- Function: void print_sets(Set set1, Set set2) --- */
227 void print_sets(Set set1, Set set2)
228 {
229  printf("\n\nSet 1 (%d nodes): ", SETsize(set1));
230  SETsort(set1, my_cmp);
231  SETtraverse(set1, print, SET_FWD);
232  printf("\nSet 2 (%d nodes): ", SETsize(set2));
233  SETsort(set2, my_cmp);
234  SETtraverse(set2, print, SET_FWD);
235 }
236 
237 /* --- Function: void print_union_diff_intersec(Set s1, Set s2) --- */
238 void print_union_diff_intersec(Set s1, Set s2)
239 {
240  Set set_union, set_diff1, set_diff2, set_intersec;
241 
242  set_union = SETunion(s1, s2);
243  set_diff1 = SETdifference(s1, s2);
244  set_diff2 = SETdifference(s2, s1);
245  set_intersec = SETintersection(s1, s2);
246 
247  SETsort(set_union, my_cmp);
248  printf("\nSet1 UNION Set2(%02d nodes) : ", SETsize(set_union));
249  SETtraverse(set_union, print, SET_FWD);
250  printf("\nSet1 DIFF Set2(%02d nodes) : ", SETsize(set_diff1));
251  SETtraverse(set_diff1, print, SET_FWD);
252  printf("\nSet2 DIFF Set1(%02d nodes) : ", SETsize(set_diff2));
253  SETtraverse(set_diff2, print, SET_FWD);
254  printf("\nSet1 INTSEC Set2(%02d nodes): ", SETsize(set_intersec));
255  SETtraverse(set_intersec, print, SET_FWD);
256 
257  SETdestroy(set_union);
258  SETdestroy(set_diff1);
259  SETdestroy(set_diff2);
260  SETdestroy(set_intersec);
261 
262  prompt_and_pause("\n\n");
263 }
264 
265 /* --- Function: void final_status(CSlist list) --- */
266 void final_status(Set s1, Set s2)
267 {
268  /* Final set status... */
269  my_clearscrn();
270  printf("--- FINAL STATUS ---\n");
271  printf("\nFinal set contents:");
272  print_sets(s1, s2);
273 }
274 
275 int main(void)
276 {
277  /* Declare YOUR variables here ! */
278  Set myset1, myset2;
279  int menu_choice;
280 
281  srand((unsigned int)time(NULL));
282 
283  if ((myset1 = SETinit(my_match, my_destroy)) == NULL) /* Initialize the set1... */
284  {
285  printf("\nFatal error... - bailing out!");
286  SETdestroy(myset1);
287  exit(-1);
288  }
289 
290  if ((myset2 = SETinit(my_match, my_destroy)) == NULL) /* Initialize the set2... */
291  {
292  printf("\nFatal error... - bailing out!");
293  SETdestroy(myset2);
294  exit(-1);
295  }
296 
297  my_clearscrn();
298  printf("--- INITIALIZING 2 SETS, %d NODES, RANDOM INTEGER DATA ---", NR_OF_ITEMS);
299 
300  /* Populate the (empty) sets.. */
301  create_random_nodes(myset1, NR_OF_ITEMS);
302  create_random_nodes(myset2, NR_OF_ITEMS);
303  /* Print set status... */
304  printf("\n\nCurrent set status: ");
305  print_sets(myset1, myset2);
306  prompt_and_pause("\n\n");
307 
308  /* Enter menu loop... */
309  do
310  {
311  menu_choice = menu(MAIN_MENU_ROW, 0, 5);
312 
313  switch (menu_choice)
314  {
315  case 1:
316  ins_node(myset1);
317  break;
318  case 2:
319  ins_node(myset2);
320  break;
321  case 3:
322  rem_node(myset1);
323  break;
324  case 4:
325  rem_node(myset2);
326  break;
327  case 5:
328  {
329  my_clearscrn();
330  printf("--- PRINT Set1 & Set2 - AND THEIR CORRESPONDING UNION, DIFF AND INTERSECTION ---");
331  print_sets(myset1, myset2);
332  printf("\n---");
333  print_union_diff_intersec(myset1, myset2);
334  }
335  break;
336  default:
337  final_status(myset1, myset2);
338  break;
339  }
340  }
341  while (menu_choice);
342 
343  /* ..and finally destroy the list. */
344  prompt_and_pause("\n\nLet's tidy up and destroy the set..- Bye!");
345  SETdestroy(myset1);
346  SETdestroy(myset2);
347 
348  return 0;
349 }