The LevAWC Project
 All Data Structures Files Functions Variables Typedefs Enumerations Macros Pages
demo01.c
1 /*
2  * _____
3  * ANSI / ___/
4  * / /__
5  * \___/
6  *
7  * Filename: demo01.c
8  * Author : Dan Levin
9  * Date : Fri Feb 20 10:11:10 2015
10  * Version : 0.51
11  * ---
12  * Description: A first demo of the library LevAWC - singly-linked lists.
13  *
14  * Revision history: (this is where you document the diffs between versions...)
15  * Date Revision
16  * 121212 Created this program the first time..
17  * 121218 After some editing I consider this hack ready for going public :-)
18  * 130205 Used the new function 'int SLISTfind_remove()' (instead of the old 'int SLISTremnode()'..)
19  * 130205 Further editing - more extensive error handling than before..
20  * 130411 Extended user interaction when inserting/removing nodes. User determines the number of operations..
21  * 150120 Started making demo1.c menu-driven.
22  * 150220 Moved some utility functions from here - to file ../utils.c
23  * 150220 Source ready for version 0.5!
24  * 150317 Updated to version 0.51
25  *
26  */
27 
28 
29 #include <stdio.h>
30 #include <stdlib.h>
31 #include <time.h>
32 #include "slist.h"
33 #include "utils.h"
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 #define NR_OF_ITEMS 10
48 
49 /* Some string macros for the main menu... */
50 #define MAIN_MENU_ROW "--- SINGLY-LINKED LIST DEMO ---\nMENU: 0=Exit 1=Add_Node 2=Rem_Node 3=Search 4=Sort 5=Print\nSelection "
51 #define MAIN_PROMPT "\nSelection <0-5>+<Enter>: "
52 
53 /* FUNCTION-DECLARATIONS */
54 /* Application-specific callbacks.. */
55 void my_destroy(void *data);
56 int my_cmp(const void *key1, const void *key2);
57 int my_match(const void *k1, const void *k2);
58 void print(const void *data);
59 
60 /* Functions handling menu selections */
61 void ins_nodes(Slist list);
62 void rem_nodes(Slist list);
63 void search_node(Slist lst);
64 void sort_list(Slist list);
65 void print_list(Slist lst);
66 void final_status(Slist list);
67 
68 /* Misc. application functions.. */
69 void create_random_nodes(Slist list, int nr_of_nodes);
70 /* END-OF-FUNCTION-DECLARATIONS */
71 
72 /* FUNCTION-DEFINITIONS - that is, the rest of the program */
73 /* --- Function: void my_destroy(void *data) --- */
74 void my_destroy(void *data)
75 {
76  free(data);
77 }
78 
79 /* --- Function: void print(const void *data) --- */
80 void print(const void *data)
81 {
82  printf(" %02d", *(int *)data);
83 }
84 
85 /* --- Function: int my_cmp(const int *key1, const int *key2) --- */
86 int my_cmp(const void *key1, const void *key2)
87 {
88  return (*(int *)key1 - *(int *)key2);
89 }
90 
91 /* --- Function: int my_match(const void *k1, const void *k2) --- */
92 int my_match(const void *k1, const void *k2)
93 {
94  return *(int *)k1 == *(int *)k2;
95 }
96 
97 /* --- Function: void create_random_nodes(Slist list, int nr_of_nodes) --- */
98 void create_random_nodes(Slist list, int nr_of_nodes)
99 {
100  int i=0, *pi, retval;
101 
102  my_clearscrn();
103  /* Initialize the list.. */
104  printf("--- CREATED A SINGLY-LINKED LIST(%d NODES)- RANDOM INTEGER DATA ---", NR_OF_ITEMS);
105 
106  do
107  {
108  pi = (int *)malloc(sizeof(int));
109  MALCHK(pi);
110 
111  *pi = rand_int(1,50);
112 
113  retval=SLISTinsnext(list, NULL, pi);
114  assert(retval == OK);
115 
116  } while (++i < nr_of_nodes);
117 
118  /* Display the list... */
119  printf("\n\nCurrent list status(%d nodes): ", SLISTsize(list));
120  SLISTtraverse(list, print, SLIST_FWD);
121  prompt_and_pause("\n\n");
122 }
123 
124 /* --- Function: void ins_nodes(Slist list) --- */
125 void ins_nodes(Slist list)
126 {
127  int tmp, *pi;
128  SlistNode node;
129  char mess[BUFSIZ];
130 
131  do
132  {
133  my_clearscrn();
134  printf("--- ADD NODE - WITH DATA=99 - AFTER USER-SPECIFIED NODE ---\n");
135  printf("\nCurrent list status(%d nodes): ", SLISTsize(list));
136  SLISTtraverse(list, print, SLIST_FWD);
137 
138  tmp = read_int("\nEnter (key)data, after which new node(key=99) will be inserted (-1=Quit): ", 0, 0);
139 
140  if (tmp == -1)
141  break;
142 
143  if ((node = SLISTfindnode(list, &tmp)) != NULL) /* Node found */
144  {
145  /* Insert node after first occurance of user-specified node */
146  pi = (int *)malloc(sizeof(int));
147  MALCHK(pi);
148 
149  *pi = 99;
150 
151  if ((SLISTinsnext(list, node, pi)) != OK)
152  {
153  printf("\nFatal error - exiting...!");
154  SLISTdestroy(list);
155  exit(-1);
156  }
157  else
158  {
159  sprintf(mess, "Node 99 will be inserted after node %d", *(int *)SLISTdata(node));
160  prompt_and_pause(mess);
161  }
162  }
163  else
164  {
165  sprintf(mess, "Error: Node %d not found...!", tmp);
166  prompt_and_pause(mess);
167  }
168  } while (TRUE);
169 }
170 
171 /* --- Function: void rem_nodes(Slist list) --- */
172 void rem_nodes(Slist list)
173 {
174  int tmp, *pi, retval;
175  char mess[BUFSIZ];
176 
177  do
178  {
179  my_clearscrn();
180  printf("--- REMOVE NODE FROM LIST ---\n");
181  printf("\nCurrent list status(%d nodes): ", SLISTsize(list));
182  SLISTtraverse(list, print, SLIST_FWD);
183 
184  tmp = read_int("\nEnter keydata for node to be removed (-1=Quit): ", 0, 0);
185 
186  if (tmp == -1)
187  break;
188 
189  /* Remove node - and free memory */
190  pi = &tmp;
191 
192  if ((retval = SLISTfind_remove(list, (void **)&pi)) != OK)
193  {
194  if (retval == 1)
195  {
196  sprintf(mess, "Error: Node %d not found..!", tmp);
197  prompt_and_pause(mess);
198  }
199  else
200  {
201  if (retval == -2)
202  printf("\nError: Match-callback is missing... - bailing out!");
203  else
204  printf("\nFatal error... - bailing out!");
205  SLISTdestroy(list);
206  exit(retval);
207  }
208  }
209  else
210  {
211  /* Removal succesful - notify user.. */
212  sprintf(mess, "Node %d will be removed..!", *(int *)pi);
213  prompt_and_pause(mess);
214  /* Free node - after being removed from list.. */
215  my_destroy(pi);
216  }
217  } while (TRUE);
218 }
219 
220 /* --- Function: void search_node(Slist lst) --- */
221 void search_node(Slist lst)
222 {
223  int tmp;
224  char mess[BUFSIZ];
225 
226  do
227  {
228  my_clearscrn();
229  printf("--- SEARCH NODE ---\n");
230  printf("\nCurrent list status(%d nodes): ", SLISTsize(lst));
231  SLISTtraverse(lst, print, SLIST_FWD);
232 
233  tmp = read_int("\nEnter keydata for node to be found (-1=Quit): ", 0, 0);
234 
235  if (tmp == -1)
236  break;
237 
238  if (SLISTfindnode(lst, &tmp) == NULL) /* Node not found.. */
239  {
240  sprintf(mess, "Node %d NOT found..!", tmp);
241  prompt_and_pause(mess);
242  }
243  else
244  {
245  /* Search succesful - notify user.. */
246  sprintf(mess, "Node %d FOUND!", tmp);
247  prompt_and_pause(mess);
248  }
249  } while (TRUE);
250 }
251 
252 /* --- Function: void sort_list(Slist list) --- */
253 void sort_list(Slist list)
254 {
255  my_clearscrn();
256  printf("--- SORT LIST ---\n");
257  SLISTsort(list, my_cmp);
258  printf("\nCurrent list status(%d nodes, ascending) : ", SLISTsize(list));
259  SLISTtraverse(list, print, SLIST_FWD);
260 
261  printf("\nCurrent list status(%d nodes, descending): ", SLISTsize(list));
262  SLISTtraverse(list, print, SLIST_BWD);
263  prompt_and_pause("\n\n");
264 }
265 
266 /* --- Function: void print_list(Slist lst) --- */
267 void print_list(Slist lst)
268 {
269  my_clearscrn();
270  printf("--- PRINT LIST ---\n");
271  /* List status... */
272  printf("\nCurrent list status(%d nodes): ", SLISTsize(lst));
273  SLISTtraverse(lst, print, SLIST_FWD);
274  prompt_and_pause("\n\n");
275 }
276 
277 /* --- Function: void final_status(Slist list) --- */
278 void final_status(Slist list)
279 {
280  my_clearscrn();
281  printf("--- FINAL STATUS ---\n");
282  /* Final list status... */
283  printf("\nFinal list contents(%d nodes): ", SLISTsize(list));
284  SLISTtraverse(list, print, SLIST_FWD);
285 }
286 
287 int main(void)
288 {
289  /* Declare YOUR variables here ! */
290  Slist mylist;
291  int menu_choice;
292 
293  /* Seed to random generator and clear the screen.. */
294  srand((unsigned int)time(NULL));
295 
296  if ((mylist = SLISTinit(my_destroy)) == NULL)
297  {
298  printf("\nFatal error... - bailing out!");
299  SLISTdestroy(mylist);
300  exit(-1);
301  }
302 
303  /* Set match-callback into list structure.. */
304  SLISTsetmatch(mylist, my_match);
305 
306  /* Populate the (empty) list.. */
307  create_random_nodes(mylist, NR_OF_ITEMS);
308 
309  /* Enter menu loop... */
310  do
311  {
312  menu_choice = menu(MAIN_MENU_ROW, 0, 5);
313 
314  switch (menu_choice)
315  {
316  case 1:
317  ins_nodes(mylist);
318  break;
319  case 2:
320  rem_nodes(mylist);
321  break;
322  case 3:
323  search_node(mylist);
324  break;
325  case 4:
326  sort_list(mylist);
327  break;
328  case 5:
329  print_list(mylist);
330  break;
331  default:
332  final_status(mylist);
333  break;
334  }
335  }
336  while (menu_choice);
337 
338  /* ..and finally destroy the list. */
339  prompt_and_pause("\n\nLet's tidy up and destroy the list..- Bye!");
340  SLISTdestroy(mylist);
341 
342  return 0;
343 }