The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo08.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo08.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 11:48:45 2015
10  * Version : 0.51
11  * ---
12  * Description: Demo of the library LevAWC - circular singly-linked lists.
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 130410 Created this program the first time..
17  * 150127 Converted this program, demo8.c, to be menu-driven.
18  * 150220 Moved some utility functions from here - to file ../utils.c
19  * 150220 Source ready for version 0.5!
20  * 150318 Source ready for version 0.51
21  *
22  */
23 
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <time.h>
27 #include "cslist.h"
28 #include "utils.h"
29 
30 #ifndef OK
31 #define OK 0
32 #endif
33 
34 #ifndef TRUE
35 #define TRUE 1
36 #endif
37 
38 #ifndef FALSE
39 #define FALSE 0
40 #endif
41 
42 #define NR_OF_ITEMS 10
43 
44 /* Some string macros for the main menu... */
45 #define MAIN_MENU_ROW "--- CIRCULAR SINGLY-LINKED LIST DEMO ---\nMENU: 0=Exit 1=Add_Node 2=Rem_Node 3=Search 4=Print\nSelection "
46 
47 /* FUNCTION-DECLARATIONS */
48 /* Application-specific callbacks */
49 void my_destroy(void *data);
50 void print(const void *data);
51 int my_cmp(const void *key1, const void *key2);
52 
53 /* Functions handling menu selections */
54 void rem_node(CSlist list);
55 void ins_node(CSlist list);
56 void search_node(CSlist lst);
57 void print_cslist(CSlist list);
58 void final_status(CSlist list);
59 
60 /* Misc. application functions.. */
61 void create_random_nodes(CSlist list, 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 create_random_nodes(CSlist list, int nr_of_nodes) --- */
90 void create_random_nodes(CSlist list, int nr_of_nodes)
91 {
92  int i=0, *pi, retval;
93 
94  do
95  {
96  pi = (int *)malloc(sizeof(int));
97  MALCHK(pi);
98 
99  *pi = rand_int(1,50);
100 
101  if (!CSLISTsize(list))
102  retval=CSLISTinsnext(list, NULL, pi);
103  else
104  retval=CSLISTinsnext(list, CSLISThead(list), pi);
105 
106  assert(retval == OK);
107 
108  } while (++i < nr_of_nodes);
109 
110  my_clearscrn();
111  printf("--- INITIALIZING A CIRCULAR, SINGLY-LINKED LIST, %d NODES, RANDOM INTEGER DATA ---\n", NR_OF_ITEMS);
112  printf("\nCurrent list status(%d nodes): ", CSLISTsize(list));
113  print_cslist(list);
114  prompt_and_pause("\n\n");
115 }
116 
117 /* --- Function: void ins_node(CSlist list) --- */
118 void ins_node(CSlist list)
119 {
120  int tmp, *pi;
121  CSlistNode node;
122  char mess[BUFSIZ];
123 
124  do
125  {
126  my_clearscrn();
127  printf("--- ADD NODE WITH DATA=99 - AFTER USER-SPECIFIED NODE ---");
128  printf("\n\nCurrent list status(%d nodes): ", CSLISTsize(list));
129  print_cslist(list);
130 
131  tmp = read_int("\nEnter (key)data, after which new node(key=99) will be inserted (-1=Quit): ", 0, 0);
132 
133  if (tmp == -1)
134  break;
135 
136  if ((node = CSLISTfindnode(list, &tmp)) != NULL) /* Node found */
137  {
138  /* Insert node after first occurance of user-specified node */
139  pi = (int *)malloc(sizeof(int));
140  MALCHK(pi);
141 
142  *pi = 99;
143 
144  if ((CSLISTinsnext(list, node, pi)) != OK)
145  {
146  printf("\nFatal error - exiting...!");
147  CSLISTdestroy(list);
148  exit(-1);
149  }
150  else
151  {
152  sprintf(mess, "Node 99 will be inserted after node %d", *(int *)CSLISTdata(node));
153  prompt_and_pause(mess);
154  }
155  }
156  else
157  {
158  sprintf(mess, "Error: Node %d not found...!", tmp);
159  prompt_and_pause(mess);
160  }
161  } while (TRUE);
162 }
163 
164 /* --- Function: void rem_node(CSlist list) --- */
165 void rem_node(CSlist list)
166 {
167  int tmp, *pi, retval;
168  char mess[BUFSIZ];
169 
170  do
171  {
172  my_clearscrn();
173  printf("--- REMOVE NODE FROM LIST ---");
174  printf("\n\nCurrent list status(%d nodes): ", CSLISTsize(list));
175  print_cslist(list);
176 
177  tmp = read_int("\nEnter (key)data for node to be removed (-1=Quit): ", 0, 0);
178 
179  if (tmp == -1)
180  break;
181 
182  /* Remove node - and free memory */
183  pi = &tmp;
184 
185  if ((retval = CSLISTfind_remove(list, (void **)&pi)) != OK)
186  {
187  if (retval == 1)
188  {
189  sprintf(mess, "Error: Node %d not found..!", *(int *)pi);
190  prompt_and_pause(mess);
191  }
192  else
193  {
194  if (retval == -2)
195  printf("\nMatch-callback is missing... - bailing out!");
196  else
197  printf("\nFatal error... - bailing out!");
198  CSLISTdestroy(list);
199  exit(retval);
200  }
201  }
202  else
203  {
204  /* Removal succesful - notify user.. */
205  sprintf(mess, "Node %d will be removed..!", *(int *)pi);
206  prompt_and_pause(mess);
207  /* Free node - after being removed from list.. */
208  my_destroy(pi);
209  }
210 
211  } while (TRUE);
212 }
213 
214 
215 /* --- Function: void search_node(CSlist lst) --- */
216 void search_node(CSlist lst)
217 {
218  int tmp;
219  CSlistNode node;
220  char mess[BUFSIZ];
221 
222  do
223  {
224  my_clearscrn();
225  printf("--- SEARCH NODE ---");
226  printf("\n\nCurrent list status(%d nodes): ", CSLISTsize(lst));
227  print_cslist(lst);
228 
229  tmp = read_int("\nEnter (key)data for node to be found (-1=Quit): ", 0, 0);
230 
231  if (tmp == -1)
232  break;
233 
234  if ((node = CSLISTfindnode(lst, &tmp)) != NULL) /* Node found */
235  {
236  sprintf(mess, "Node %d FOUND..!", *(int *)CSLISTdata(node));
237  prompt_and_pause(mess);
238  }
239  else
240  {
241  sprintf(mess, "Node %d NOT found...!", tmp);
242  prompt_and_pause(mess);
243  }
244  } while (TRUE);
245 }
246 
247 /* --- Function: void print_cslist(CSlist list) --- */
248 void print_cslist(CSlist list)
249 {
250  CSLISTtraverse(list, print);
251 }
252 
253 /* --- Function: void final_status(CSlist list) --- */
254 void final_status(CSlist list)
255 {
256  my_clearscrn();
257  printf("--- FINAL STATUS ---\n");
258  /* Final list status... */
259  printf("\nFinal list contents(%d nodes): ", CSLISTsize(list));
260  print_cslist(list);
261 }
262 
263 int main(void)
264 {
265  /* Declare YOUR variables here ! */
266  CSlist mycslist;
267  int menu_choice;
268 
269  srand((unsigned int)time(NULL));
270 
271  if ((mycslist = CSLISTinit(my_destroy)) == NULL) /* Initialize the list */
272  {
273  printf("\nFatal error... - bailing out!");
274  CSLISTdestroy(mycslist);
275  exit(-1);
276  }
277 
278  /* Populate the (empty) list.. */
279  create_random_nodes(mycslist, NR_OF_ITEMS);
280  /* Set the match-callback.. */
281  CSLISTsetmatch(mycslist, my_match);
282 
283  /* Enter menu loop... */
284  do
285  {
286  menu_choice = menu(MAIN_MENU_ROW, 0, 4);
287 
288  switch (menu_choice)
289  {
290  case 1:
291  ins_node(mycslist);
292  break;
293  case 2:
294  rem_node(mycslist);
295  break;
296  case 3:
297  search_node(mycslist);
298  break;
299  case 4:
300  my_clearscrn();
301  printf("--- PRINT CIRCULAR LIST ---\n\nCurrent list status(%d nodes): ", CSLISTsize(mycslist));
302  print_cslist(mycslist);
303  prompt_and_pause("\n\n");
304  break;
305  default:
306  final_status(mycslist);
307  break;
308  }
309  }
310  while (menu_choice);
311 
312  /* ..and finally destroy the list. */
313  prompt_and_pause("\n\nLet's tidy up and destroy the list..- Bye!");
314  CSLISTdestroy(mycslist);
315 
316  return 0;
317 }