File: voidlist.c

package info (click to toggle)
safecopy 1.7-6
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, bullseye, sid
  • size: 2,388 kB
  • sloc: ansic: 2,751; sh: 1,925; makefile: 19
file content (286 lines) | stat: -rw-r--r-- 7,990 bytes parent folder | download | duplicates (5)
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
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
/**
 * This file is copyright ©2009 Corvus Corax
 * Distributed under the terms of the GPL version 2 or higher
 */
/*This file contains a void list class, a generic list class
  with standard functions*/

/*Maybe i should be proud of this, this is a classical!
  I always said "Who needs C++?"
  >;>>> */

#include <stdlib.h>
/* Private structures --------------------------------------------------*/

struct voidident;
struct voiddata;

struct voidentry {
   struct voidident *identity;
   struct voiddata *data;
   struct voidentry *next,*prev;
};

/*The structure sector to save a single entry*/

/* Public structures --------------------------------------------------*/

struct voidlist {
   struct voidentry *first,*last;
   int listcount;
};

/*The structure voidlist, public itself, but members are private*/

/* Public functions ---------------------------------------------------*/

struct voidlist* voidlist_new() {
/*A constructor*/
   struct voidlist* newlst;

   newlst=(struct voidlist*)malloc(sizeof(struct voidlist));
   if (!newlst) return NULL;

   newlst->first=NULL;
   newlst->last=NULL;
   newlst->listcount=0;
   return newlst;
}

/* ------------------------------------------------------------------- */

int voidlist_remitem (	struct voidlist* list,
			struct voidident* item,
			int (*greater)(struct voidident *frst, struct voidident *scnd),
			int (*equality)(struct voidident *frst, struct voidident *scnd),
			int (*freecontent)(struct voidident *identity,struct voiddata *data)) {
/*Removes an entry from the list*/
/*0 for found, 1 for not found, -1 for error */

   struct voidentry *member;

   if (!list) return -1;

   member=list->first;
   while (member!=NULL) {
      if (greater(member->identity,item)) {
         return 1;
         /*Requested member was not found, ergo est nada niente never noupe*/
      } else {
         if (equality(member->identity,item)) {
            /*We have a candidate*/
	    if (member->prev==NULL) {
	       /*And its the first in the list*/
	       list->first=member->next;
	    } else {
	       /*Or not <g>*/
	       member->prev->next=member->next;
	    }
	    if (member->next==NULL) {
	       /*But its the last in the list*/
	       list->last=member->prev;
	    } else {
	       /*Or not <g>*/
	       member->next->prev=member->prev;
	    }
	    list->listcount--;
	    /*Ok member has been remobed from list, so delete it*/
	    freecontent(member->identity,member->data);
	    free(member);
	    return 0;
	    /*Since we have a sorted list, this entry is sure to have
	      existed only once --- or has it ? happy debugging <g>*/
         }
	 member=member->next;
      }
   }
   /*Requested member was not found, ergo est nada niente never noupe*/
   return 1;

}

/* ------------------------------------------------------------------- */

int voidlist_kill(	struct voidlist* list,
			int (*freecontent)(struct voidident* identity,struct voiddata* data)){
/*A destructor, 0 on success, -1 on error*/

   struct voidentry *member;

   if (!list) return -1;

   while (list->first!=NULL) {
      member=list->first;
      list->first=member->next;
      freecontent(member->identity,member->data);
      free(member);
   }
   /* I now kill those entrys manually, because voidlist remitem needs far too much
      extra functions to run. too much overhead. i dont need comparisation for
      annihilation. who cares about colateral damage if you want to leave ashes*/
   /*I explicitly destroy list consistency here by the way, so there is no return
     when started. */

   free(list);
   return 0;
}

/* ------------------------------------------------------------------- */

int voidlist_additem (	struct voidlist* list,
			struct voidident* item,
			struct voiddata* data,
			int (*greater)(struct voidident *frst, struct voidident *scnd),
			int (*equality)(struct voidident *frst, struct voidident *scnd),
			int (*freecontent)(struct voidident *identity, struct voiddata *data)) {
/*Adds an entry to the list*/
/*Returns 0 for success and 1 for data change, -1 for error*/

   struct voidentry *member,*newmember;

   if (!list) return -1;
   
   member=list->first;
   while (member!=NULL) {
      /*We have entrys in the list*/
      if (greater(member->identity,item)) {
         /*We are behind the position where this should be*/
	 newmember=(struct voidentry*) malloc (sizeof(struct voidentry));
	 newmember->next=member;
	 newmember->prev=member->prev;
	 newmember->identity=item;
	 newmember->data=data;
	 /*New entry created*/
	 if (member->prev==NULL) {
	    /*ah yes. there is a list, but we just insert at the beginning*/
	    list->first=newmember;
	 } else {
	    /*we are just somewhere between, so do standard insert*/
	    member->prev->next=newmember;
	 }
	 member->prev=newmember;
	 list->listcount++;
	 /*And inserted*/
	 return 0;
      } else {
         /*We dont have the position yet*/
	 if (equality(item,member->identity)) {
	    /*Correct me, we are exatcly on the right position which meens
	      already there*/
	    freecontent(member->identity,member->data);
	    member->identity=item;
	    member->data=data;
	    return 1;
	 }
	 member=member->next;
      }
   }
   /*Ok we are at the very end*/
   newmember=(struct voidentry*) malloc (sizeof(struct voidentry));
   newmember->next=NULL;
   newmember->prev=list->last;
   newmember->identity=item;
   newmember->data=data;
   /*Create the new entry*/
   list->last=newmember;
   if (newmember->prev==NULL) {
      list->first=newmember;
   } else {
      newmember->prev->next=newmember;
   }
   list->listcount++;
   /*Put it into the list*/
   return 0;


}

/* ------------------------------------------------------------------- */

struct voiddata* voidlist_item (struct voidlist* list,
				struct voidident* item,
				int (*greater)(struct voidident *frst, struct voidident *scnd),
				int (*equality)(struct voidident *frst, struct voidident *scnd)){
/*Gives out the data of one entry, NULL for error and not found*/
   struct voidentry* member;

   if (!list) return NULL;

   member=list->first;
   while (member!=NULL) {
      if (greater(member->identity,item)) {
         return NULL;
         /*Requested member was not found, ergo est nada niente never noupe*/
      } else {
	 if (equality(member->identity,item)) {
	    return member->data;
	    /*We found it!*/
	 }
	 member=member->next;
      }
   }
   return NULL;
}
/* ------------------------------------------------------------------- */

int voidlist_all (	struct voidlist* list,
			int (*listprint)(int number, struct voidident *identity, struct voiddata *data, void *userdata ),
			void *userdata
			){
/*Gives out all the data via listprint*/
/*Gives back 1 when list is empty and 0 if not */
/*-1 on error*/
   int t=0;
   struct voidentry *member;

   if (!list) return -1;

   member=list->first;
   while (member!=NULL) {
      listprint (t++,member->identity,member->data,userdata);
      member=member->next;
   }

   if (t>0) {
      return 0;
   } else {
      return 1;
   }
}

/* ------------------------------------------------------------------- */

int voidlist_members (	struct voidlist* list){
/*Gives back the amount of List members*/

   if (!list) return 0;
   return list->listcount;
}

/* ------------------------------------------------------------------- */

struct voidident* voidlist_first (struct voidlist* list){
/*Gives back the !identifier! (not the data) of the first item*/

   if (!list) return NULL;

   if (list->first!=NULL) {
      return list->first->identity;
   } else {
      return NULL;
   }
}
/* ------------------------------------------------------------------- */

struct voidident* voidlist_last (struct voidlist* list){
/*Gives back the !identifier! (not the data) of the last item*/

   if (!list) return NULL;

   if (list->last!=NULL) {
      return list->last->identity;
   } else {
      return NULL;
   }
}
/* -End--------------------------------------------------------------- */