-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathlistTest.c
247 lines (211 loc) · 9.42 KB
/
listTest.c
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
/**
* @copyright (c) 2016 Abelardo López Lagunas. All rights reserved.
*
* @file listTest.c
*
* @author Abelardo López Lagunas
*
* @brief This program tests how the list-management routines work.
*
* @date Fri 06.Feb.2015 14:33 CST
*
* Usage The program reads a text file with the elements that will
* be converted into nodes in a linked list. The usage form is:
* @code
* listTest file.txt
* @endcode
*
* References Based on my own code for the Generic Linked lists
*
* File formats:
* The input file should have two elements per line in ASCII
* format. The first one is a number and the second one is a
* string.
*
* Restrictions:
* If the input file is not in ASCII format the program exits.
*
* Revision history:
*
* Fri Jan 30 15:34 2014 - Added more tests for the insertion
* and deletion at the head & middle.
* Sun Feb 01 14:47 2014 - Separated the user defined functions
* into their own files.
* Tue Feb 03 11:30 2014 - Commented out the Sort and Duplicate
* list functions that were not in the
* TC2025 assignment.
* Fri 06 Feb 2015 14:33 - Added doxygen documentation commands
* Thu 26 Feb 2015 12:08 - Added final tests for the library
* Thu 05 May 2016 10:52 - Changed code to use Glib for lists
*
* @warning On any unrecoverable error, the program exits
*
* @note This code will be used as a tutorial on pointers and data
* structures, in particular linked lists.
*
*/
#include <stdio.h> // Used for printf
#include <stdlib.h> // Used for malloc, & EXIT codes
#include <assert.h> // Used for the assert macro
#include <string.h> // For strcmp, strlen, strcpy
#include <glib.h> // Bring in glib for all doubly-linked list functions
#include "FileIO.h" // Used for the file access support functions
#include "UserDefined.h" // All the user defined functions
/** @def NUMPARAMS
* @brief This is the expected number of parameters from the command line.
*/
#define NUMPARAMS 2
/*************************************************************************
* Main entry point *
*************************************************************************/
int main (int argc, const char * argv[]) { // Program entry point
FILE *fp; // Pointer to the file
GList * theList_p = NULL; // Used to test the list operations
GList * item_p = NULL; // Used in the find operation
node_p aNode_p; // Pointer to a node in the list
int nodeValue; // Test integer for arbitrary integer search
/* Check if the number of parameters is correct */
if (argc < NUMPARAMS){
printf("Need a file with the test data\n");
printf("Abnormal termination\n");
exit (EXIT_FAILURE);
} else {
fp = fopen (argv[1],"r"); // Open file for read operation
if (!fp) { // There is an error
printf ("The filename: %s does not exist or is corrupted\n",
argv[1]);
printf ("Abnormal termination\n");
exit (EXIT_FAILURE); // Terminate the program
} else {
while (!feof(fp)){
// Allocate memory for new item from the input file
/* Note: evaluation order of function arguments is
* implementation dependent and since both functions read
* from the SAME input file this can cause problems in some
* UNIX flavors (e.g. linux/gcc) so serialize the file
* access
*/
int number = GetInt(fp);
char * string = GetString(fp);
aNode_p = NewItem(number, string);
#ifdef DEBUG
printf("Integer read is %d:\n", aNode_p->number);
printf("String read is %s:\n", aNode_p->theString);
#endif
/***** Test insertion at the Tail *****/
theList_p = g_list_append(theList_p, aNode_p);
#ifdef DEBUG
assert(theList_p != NULL);
#else
if (theList_p == NULL)
perror("Could not insert node");
#endif
}
/***** Test deletion at the tail *****/
printf("Original list:\n");
if (PrintList(theList_p) != EXIT_SUCCESS)
printf("Error printing the list\n");
aNode_p = g_list_last(theList_p)->data; // Last element address
theList_p = g_list_remove(theList_p, aNode_p); // Remove node
FreeItem(aNode_p); // Deallocate data
printf("\n Test deletion from the Tail:\n");
if (PrintList(theList_p) != EXIT_SUCCESS)
printf("Error printing the list\n");
/****** Test Insertion at the Head *****/
aNode_p = NewItem(9, "Gyro Gearloose"); // New element
#ifdef DEBUG
printf("Integer to be inserted at the head %d:\n",
aNode_p->number);
printf("String to be inserted at the head %s:\n",
aNode_p->theString);
#endif
theList_p = g_list_prepend(theList_p, aNode_p);
printf("\n Test insertion at the Head:\n");
if (PrintList(theList_p) != EXIT_SUCCESS)
printf("Error printing the list\n");
/***** Test deletion at the head *****/
aNode_p = g_list_first(theList_p)->data; // First element address
theList_p = g_list_remove(theList_p, aNode_p); // Remove node
#ifdef DEBUG
assert(aNode_p != NULL);
#else
if (aNode_p == NULL)
perror("Could not remove first element from the list");
#endif
FreeItem(aNode_p); // Deallocate data
printf("\n Test deletion from the Head:\n");
if (PrintList(theList_p) != EXIT_SUCCESS)
printf("Error printing the list\n");
/***** Test finding a node in the list *****/
item_p = FindInList(theList_p, "Donald", SINGLESTR); // Get index
if (item_p == NULL){
perror("Error: failed to find selected node \n");
}
/***** Test insertion in the middle *****/
aNode_p = NewItem(10, "Launchpad"); // New element
// Insert data before item_p
theList_p = g_list_insert_before(theList_p, item_p, aNode_p);
#ifdef DEBUG
assert(theList_p != NULL);
#else
if (theList_p == NULL)
perror("Could not insert element somewhere in the middle");
#endif
printf("\n Test insertion in the middle:\n");
if (PrintList(theList_p) != EXIT_SUCCESS)
printf("Error printing the list\n");
/***** Test deletion in the middle & finding a string *****/
item_p = FindInList(theList_p, "Donald", SINGLESTR);
if (item_p == NULL){
perror("Error: failed to find selected node \n");
} else {
aNode_p = item_p->data;
printf("\nFound element in the list\n");
PrintItem(aNode_p);
theList_p = g_list_remove(theList_p, aNode_p); // Remove node
#ifdef DEBUG
assert(theList_p != NULL);
#else
if (theList_p == NULL)
perror("Could not remove element from middle of the list");
#endif
FreeItem(aNode_p); // Deallocate data
printf("\n Test deletion from middle:\n");
if (PrintList(theList_p) != EXIT_SUCCESS)
printf("Error printing the list\n");
}
/**** Test finding a number in the list ****/
nodeValue = 6;
item_p = FindInList(theList_p, &nodeValue, SINGLEINT);
if (item_p == NULL){
printf("Error: failed to find selected node \n");
} else {
printf("\nFound element %d in the list: \n", nodeValue);
PrintItem(item_p->data);
}
/***** Test copying the list *****/
printf("\nCreating a copy of the list\n");
item_p = CopyList(theList_p);
if (item_p == NULL){
printf("Error: failed to copy the list \n");
} else {
PrintList(item_p);
}
/***** Test sorting the list by its number field *****/
item_p = g_list_sort(item_p, CompareItems);
if (item_p == NULL){
printf("Error: failed to sort copy the list \n");
} else {
printf("Sorted copy\n");
PrintList(item_p);
}
/***** Destroy the list *****/
if (DestroyList(theList_p) != EXIT_SUCCESS)
perror("The list was not destroyed successfully");
if (DestroyList(item_p) != EXIT_SUCCESS)
perror("The second list was not destroyed successfullt");
}
fclose (fp); /* Close the input data file */
return (EXIT_SUCCESS);
}
}