1
2 /*-
3 *
4 * New BSD License 2006
5 *
6 * Copyright (c) 2006, Jorgen Lundman
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted provided that the following conditions are
11 * met:
12 *
13 * 1 Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2 Redistributions in binary form must reproduce the above
16 * copyright notice, this list of conditions and the following
17 * disclaimer in the documentation and/or other materials provided
18 * with the distribution.
19 * 3 Neither the name of the stuff nor the names of its contributors
20 * may be used to endorse or promote products derived from this
21 * software without specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
24 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
25 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
26 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
27 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
28 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
29 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
30 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
31 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
32 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
33 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
34 *
35 */
36
37 #include <stdio.h>
38 #include <stdlib.h>
39
40
41 #include "object.h"
42
43
44
45 // Start of our linked list. It is made static so it can not be touched
46 // outside of this module. You should call the functions provided.
47
48 static object_t *object_listhead = NULL;
49
50
51
52
53
54
55
object_new(void)56 object_t *object_new(void)
57 {
58 object_t *retval;
59
60
61 retval = (object_t *)malloc(sizeof(*retval));
62
63 if (!retval) {
64 perror("object_new");
65 exit(-1);
66 }
67
68
69 // Clear the node, always good practise.
70 memset(retval, 0, sizeof(*retval));
71
72
73 // Insert into linked list.
74 // For this sample, a linked list is never really required but
75 // I have included it as an example, and therefor we can do
76 // object_free_all, as well as a "iterate all connected" command.
77 retval->next = object_listhead;
78 object_listhead = retval;
79
80 // Return it to the caller
81 return retval;
82
83 }
84
85
86
87
88
object_free(object_t * node)89 void object_free(object_t *node)
90 {
91 object_t *prev, *runner;
92
93 if (node->username) {
94 free( node->username );
95 node->username = NULL;
96 }
97
98
99 // Remove it from the linked list.
100
101 for (prev = NULL, runner = object_listhead;
102 runner;
103 prev = runner, runner = runner->next) {
104
105
106 if (runner == node) { // This is the one to remove
107
108 if (!prev) {
109
110 // If no previous node, then it's at the start of the list
111
112 object_listhead = runner->next;
113
114 } else {
115
116 // In the middle somewhere
117
118 prev->next = runner->next;
119
120 }
121
122 break; // Stop spinning in the for-loop.
123
124 } // if runner == node
125
126 } // for
127
128
129 // Release it
130 free( node );
131
132 }
133
134
135
object_free_all(void)136 void object_free_all(void)
137 {
138
139 // Since we call object_free() which re-arranges the linked-list
140 // we can't just iterate it. So, slightly different semantics.
141
142 while( object_listhead ) {
143
144 object_free( object_listhead );
145
146 }
147
148
149 }
150
151
152
153 //
154 // Find a particular node, or, iterate the list.
155 //
156 // IN: comparison function, expected to return 0 on match
157 // IN: two optional arguments that are simply passed on
158 // OUT: pointer to matching node, or NULL if end reached
159 //
object_find(int (* compare)(object_t *,void *,void *),void * optarg1,void * optarg2)160 object_t *object_find( int (*compare)(object_t *, void *, void *),
161 void *optarg1, void *optarg2)
162 {
163 object_t *runner;
164
165 for (runner = object_listhead; runner; runner = runner->next) {
166
167 if (!compare(runner, optarg1, optarg2)) {
168
169 // Found it, apparently
170 return runner;
171
172 }
173
174 }
175
176 // Didn't find it
177 return NULL;
178
179 }
180
181