The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo12.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo12.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 13:23:46 2015
10  * Version : 0.51
11  * ---
12  * Description: A demo program testing/showing the Graph ADT
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 150204 Created this demo - 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  * 150320 This source ready for version 0.51!
20  *
21  */
22 
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <time.h>
26 #include "graph.h"
27 #include "utils.h"
28 
29 /* --- MACRO DEFINITIONS --- */
30 #ifndef OK
31 #define OK 0
32 #endif
33 
34 #define ERR_DUPL 1
35 #define ERR_VTX_OR_EDGE_MISSING -2
36 #define ERR_VTX_NOT_ISOL -3
37 #define ERR_FATAL -1
38 
39 #define NR_OF_VERTICES 7
40 #define NR_OF_EDGES 20
41 
42 /* Some string macros for the main menu... */
43 #define MAIN_MENU_ROW "--- GRAPH DEMO ---\nMENU: 0=Exit 1=Add_Vertex 2=Rem_Vertex 3=Add_Edge 4=Rem_Edge 5=Print\nSelection "
44 
45 /* FUNCTION DECLARATIONS */
46 void my_destroy(void *data);
47 void print(const void *data);
48 int my_cmp(const void *key1, const void *key2);
49 int my_match(const void *k1, const void *k2);
50 
51 /* Menu selections */
52 void ins_vertex(Graph gr);
53 void rem_vertex(Graph gr);
54 void ins_edge(Graph gr);
55 void rem_edge(Graph gr);
56 void print_graph(Graph gr);
57 void final_status(Graph gr);
58 
59 /* Misc. application functions.. */
60 void create_rand_vertices(Graph gr, int nr_of_nodes);
61 /* END-OF-FUNCTION-DECLARATIONS */
62 
63 /* FUNCTION DEFINITIONS - the rest of the program */
64 /* --- Function: void my_destroy(void *data) --- */
65 void my_destroy(void *data)
66 {
67  free(data);
68 }
69 
70 /* --- Function: void printvtx(const void *data) --- */
71 void printvtx(const void *data)
72 {
73  printf("%02d", *(int *)data);
74 }
75 
76 /* --- Function: void printvtx(const void *data) --- */
77 void printedge(const void *data)
78 {
79  printf("%02d ", *(int *)data);
80 }
81 
82 /* --- Function: int my_cmp(const int *key1, const int *key2) --- */
83 int my_cmp(const void *key1, const void *key2)
84 {
85  return (*(int *)key1 - *(int *)key2);
86 }
87 
88 /* --- Function: int my_match(const void *k1, const void *k2) --- */
89 int my_match(const void *k1, const void *k2)
90 {
91  return *(int *)k1 == *(int *)k2;
92 }
93 
94 /* --- Function: void add_nodes(Graph gr, int nr_of_nodes) --- */
95 void create_rand_vertices(Graph gr, int nr_of_nodes)
96 {
97  int i=0, *pi, retval, dupctr=0;
98 
99  do
100  {
101  pi = (int *)malloc(sizeof(int));
102  *pi = rand_int(1,99);
103 
104  if ((retval = GRAPHinsvertex(gr, pi)) != OK) /* Insertion failed... */
105  {
106  if (retval == ERR_DUPL) /* Duplicate key value.. */
107  {
108  dupctr++;
109  my_destroy(pi); /* Free node - since duplicate.. */
110  }
111  else
112  {
113  if (retval == ERR_FATAL)
114  {
115  prompt_and_pause("\nError: Fatal error - bailing out..!\n");
116  exit(-1);
117  }
118  }
119  }
120  } while (++i < nr_of_nodes);
121 
122  my_clearscrn();
123  printf("--- INITIALIZING A GRAPH, %d VERTICES, RANDOM INTEGER DATA ---", NR_OF_VERTICES);
124  printf("\n\nCurrent graph status:");
125  print_graph(gr);
126  printf("\n\n%d/%d successful insertion(s) -- %d duplicates rejected...", GRAPHvcount(gr), nr_of_nodes, dupctr);
127  prompt_and_pause("\n\n");
128 }
129 
130 /* --- Function: void ins_vertex(Graph gr) --- */
131 void ins_vertex(Graph gr)
132 {
133  int tmp, *pi, retval;
134  char mess[BUFSIZ];
135 
136  do
137  {
138  my_clearscrn();
139  printf("--- ADD VERTEX ---");
140  printf("\n\nCurrent graph status(%d vertices/%d edges): ", GRAPHvcount(gr), GRAPHecount(gr));
141  print_graph(gr);
142 
143  tmp = read_int("\nEnter data for vertex to be inserted (-1=Quit): ", 0, 0);
144 
145  if (tmp == -1)
146  break;
147 
148  pi = (int *)malloc(sizeof(int));
149  *pi = tmp;
150 
151  if ((retval = GRAPHinsvertex(gr, pi)) != OK) /* Insertion failed... */
152  {
153  /* Do some error handling here.. */
154  if (retval == ERR_DUPL) /* Duplicate key value.. */
155  {
156  sprintf(mess, "\nError: Vertex %d duplicate - insertion failed..", *pi);
157  prompt_and_pause(mess);
158  my_destroy(pi); /* Free node - since being duplicate.. */
159  }
160  else
161  {
162  prompt_and_pause("\nError: Fatal error - bailing out..!\n");
163  exit(-1);
164  }
165  }
166  else
167  {
168  /* Insertion succesful - notify user.. */
169  sprintf(mess, "\nVertex %d will be inserted..", *(int *)pi);
170  prompt_and_pause(mess);
171  }
172  } while (1);
173 }
174 
175 /* --- Function: void rem_vertex(Graph gr) --- */
176 void rem_vertex(Graph gr)
177 {
178  int tmp, *pi, retval;
179  char mess[BUFSIZ];
180 
181  do
182  {
183  my_clearscrn();
184  printf("--- REMOVE VERTEX ---");
185  printf("\n\nCurrent graph status(%d vertices/%d edges): ", GRAPHvcount(gr), GRAPHecount(gr));
186  print_graph(gr);
187 
188  tmp = read_int("\nEnter data for vertex to be removed (-1=Quit): ", 0, 0);
189 
190  if (tmp == -1)
191  break;
192 
193  pi = &tmp;
194 
195  if ((retval = GRAPHremvertex(gr, (void **)&pi)) != OK) /* Vertex removal failed.. */
196  {
197  /* Do some error handling here.. */
198  if (retval == ERR_VTX_OR_EDGE_MISSING)
199  {
200  sprintf(mess, "\nError: Vertex %d not found - removal failed..", *(int *)pi);
201  prompt_and_pause(mess);
202  }
203  else
204  {
205  if (retval == ERR_VTX_NOT_ISOL)
206  {
207  sprintf(mess, "\nError: Vertex %d not isolated - removal failed..", *(int *)pi);
208  prompt_and_pause(mess);
209  }
210  else
211  {
212  printf("\nError: Fatal failure - bailing out...");
213  exit(retval);
214  }
215  }
216  }
217  else
218  {
219  /* Removal succesful - notify user.. */
220  sprintf(mess, "\nVertex %d will be removed..!", *(int *)pi);
221  prompt_and_pause(mess);
222  /* Free node - after being removed from graph.. */
223  my_destroy(pi);
224  }
225  } while (1);
226 }
227 
228 /* --- Function: void ins_edge(Graph gr) --- */
229 void ins_edge(Graph gr)
230 {
231  int tmp1, tmp2, *pi, retval;
232  char mess[BUFSIZ];
233 
234  do
235  {
236  my_clearscrn();
237  printf("--- ADD EDGE ---");
238  printf("\n\nCurrent graph status(%d vertices/%d edges): ", GRAPHvcount(gr), GRAPHecount(gr));
239  print_graph(gr);
240 
241  tmp1 = read_int("\nEnter data for first vertex of edge to be created (-1=Quit): ", 0, 0);
242 
243  if (tmp1 == -1)
244  break;
245 
246  tmp2 = read_int("Enter data for adjacent vertex of edge to be created (-1=Quit): ", 0, 0);
247 
248  if (tmp2 == -1)
249  break;
250 
251  pi = (int *)malloc(sizeof(int));
252  *pi = tmp2;
253 
254  if ((retval = GRAPHinsedge(gr, &tmp1, pi)) != OK) /* Edge insertion failed.. */
255  {
256  /* Do some error handling here.. */
257  if (retval == ERR_DUPL)
258  {
259  sprintf(mess, "\nError: Duplicate edge - between %d and %d..", tmp1, *(int *)pi);
260  prompt_and_pause(mess);
261  my_destroy(pi);
262  }
263  else
264  {
265  if (retval == ERR_VTX_OR_EDGE_MISSING)
266  {
267  sprintf(mess, "\nError: Vertex not found - insertion failed..");
268  prompt_and_pause(mess);
269  my_destroy(pi);
270  }
271  else
272  {
273  printf("\nError: Fatal failure - bailing out...");
274  exit(retval);
275  }
276  }
277  }
278  else
279  {
280  /* Insertion succesful - notify user.. */
281  sprintf(mess, "\nEdge between vertex %d and %d will inserted..!", tmp1, *(int *)pi);
282  prompt_and_pause(mess);
283  }
284  } while (1);
285 }
286 
287 /* --- Function: void rem_edge(Graph gr) --- */
288 void rem_edge(Graph gr)
289 {
290  int tmp1, tmp2, *pi, retval;
291  char mess[BUFSIZ];
292 
293  do
294  {
295  my_clearscrn();
296  printf("--- REMOVE EDGE ---");
297  printf("\n\nCurrent graph status(%d vertices/%d edges): ", GRAPHvcount(gr), GRAPHecount(gr));
298  print_graph(gr);
299 
300  tmp1 = read_int("\nEnter data for first vertex of edge to be removed (-1=Quit): ", 0, 0);
301 
302  if (tmp1 == -1)
303  break;
304 
305  tmp2 = read_int("Enter data for adjacent vertex of edge to be removed (-1=Quit): ", 0, 0);
306 
307  if (tmp2 == -1)
308  break;
309 
310  pi = &tmp2;
311 
312  if ((retval = GRAPHremedge(gr, &tmp1, (void **)&pi)) != OK) /* Edge removal failed.. */
313  {
314  /* Do some error handling here.. */
315  if (retval == ERR_VTX_OR_EDGE_MISSING)
316  {
317  sprintf(mess, "\nError: Edge between %d and %d not found..", tmp1, *(int *)pi);
318  prompt_and_pause(mess);
319  }
320  else
321  {
322  printf("\nError: Fatal error - bailing out...");
323  exit(retval);
324  }
325  }
326  else
327  {
328  /* Removal succesful - notify user.. */
329  sprintf(mess, "\nEdge between %d and %d will be removed..!", tmp1, *(int *)pi);
330  prompt_and_pause(mess);
331  /* Free node - after being removed from graph.. */
332  my_destroy(pi);
333  }
334  } while (1);
335 }
336 
337 /* --- Function: void print_graph(Graph gr) --- */
338 void print_graph(Graph gr)
339 {
340  GRAPHprint(gr, printvtx, printedge);
341 }
342 
343 /* --- Function: void final_status(Graph gr) --- */
344 void final_status(Graph gr)
345 {
346  my_clearscrn();
347  printf("--- FINAL STATUS ---");
348  printf("\n\nFinal graph status(%d vertices/%d edges): ", GRAPHvcount(gr), GRAPHecount(gr));
349  GRAPHprint(gr, printvtx, printedge);
350 }
351 
352 int main(void)
353 {
354  /* Declare YOUR variables here ! */
355  Graph mygraph;
356  int menu_choice;
357 
358  srand((unsigned int)time(NULL));
359 
360  if ((mygraph = GRAPHinit(my_match, my_destroy)) == NULL)
361  {
362  printf("\nFatal error - bailing out...\n!");
363  exit(-1);
364  }
365 
366  /* Initialize - and add random vertices to the graph... */
367  create_rand_vertices(mygraph, NR_OF_VERTICES);
368 
369  /* Enter menu loop.. */
370  do
371  {
372  menu_choice = menu(MAIN_MENU_ROW, 0, 5);
373 
374  switch (menu_choice)
375  {
376  case 1:
377  ins_vertex(mygraph);
378  break;
379  case 2:
380  rem_vertex(mygraph);
381  break;
382  case 3:
383  ins_edge(mygraph);
384  break;
385  case 4:
386  rem_edge(mygraph);
387  break;
388  case 5:
389  my_clearscrn();
390  printf("--- PRINT GRAPH AND EDGES ---\n");
391  print_graph(mygraph);
392  prompt_and_pause("\n\n");
393  break;
394  default:
395  final_status(mygraph);
396  break;
397  }
398  }
399  while (menu_choice);
400 
401  prompt_and_pause("\n\nLet's tidy up and destroy the graph..- Bye!");
402 
403  GRAPHdestroy(mygraph);
404 
405  return 0;
406 
407 }