Mercurial > dillo_port1.3
annotate src/klist.c @ 2048:5060d415a85a
clickable menu items (even those introducing submenus) MUST have callbacks
I clicked on the "Panel size" item itself instead of any of the
options in its submenu, and: Segfault!
author | corvid <corvid@lavabit.com> |
---|---|
date | Thu, 26 May 2011 02:51:18 +0000 |
parents | aa1b2cac9edc |
children |
rev | line source |
---|---|
0 | 1 /* |
2 * File: klist.c | |
3 * | |
35 | 4 * Copyright 2001-2007 Jorge Arellano Cid <jcid@dillo.org> |
0 | 5 * |
6 * This program is free software; you can redistribute it and/or modify | |
7 * it under the terms of the GNU General Public License as published by | |
8 * the Free Software Foundation; either version 3 of the License, or | |
9 * (at your option) any later version. | |
10 */ | |
11 | |
12 /* | |
13 * A simple ADT for Key-Data pairs | |
14 * | |
15 * NOTE: this ADT is not perfect. The possibility of holding a Key, after | |
16 * its data has been removed, long enough for the key-counter to reset and | |
17 * reuse the same key is very low, but EXISTS. So, the responsibility | |
18 * remains with the caller. | |
19 */ | |
20 | |
21 #include "klist.h" | |
22 | |
23 | |
24 /* | |
25 * Compare function for searching data by its key | |
26 */ | |
27 static int Klist_node_by_key_cmp(const void *Node, const void *key) | |
28 { | |
29 return ((KlistNode_t *)Node)->Key - VOIDP2INT(key); | |
30 } | |
31 | |
32 /* | |
24 | 33 * Compare function for searching data by node |
34 */ | |
35 static int Klist_node_by_node_cmp(const void *Node1, const void *Node2) | |
36 { | |
37 return ((KlistNode_t *)Node1)->Key - ((KlistNode_t *)Node2)->Key; | |
38 } | |
39 | |
40 /* | |
0 | 41 * Return the data pointer for a given Key (or NULL if not found) |
42 */ | |
43 void *a_Klist_get_data(Klist_t *Klist, int Key) | |
44 { | |
45 void *aux; | |
46 | |
47 if (!Klist) | |
48 return NULL; | |
49 aux = dList_find_sorted(Klist->List, INT2VOIDP(Key), Klist_node_by_key_cmp); | |
50 return (aux) ? ((KlistNode_t*)aux)->Data : NULL; | |
51 } | |
52 | |
53 /* | |
54 * Insert a data pointer and return a key for it. | |
55 */ | |
56 int a_Klist_insert(Klist_t **Klist, void *Data) | |
57 { | |
58 KlistNode_t *Node; | |
59 | |
60 if (!*Klist) { | |
61 (*Klist) = dNew(Klist_t, 1); | |
62 (*Klist)->List = dList_new(32); | |
63 (*Klist)->Clean = 1; | |
64 (*Klist)->Counter = 0; | |
65 } | |
66 | |
67 /* This avoids repeated keys at the same time */ | |
68 do { | |
69 if (++((*Klist)->Counter) == 0) { | |
70 (*Klist)->Counter = 1; | |
71 (*Klist)->Clean = 0; | |
72 } | |
73 } while (!((*Klist)->Clean) && | |
74 a_Klist_get_data((*Klist), (*Klist)->Counter)); | |
75 | |
76 Node = dNew(KlistNode_t, 1); | |
77 Node->Key = (*Klist)->Counter; | |
78 Node->Data = Data; | |
24 | 79 dList_insert_sorted((*Klist)->List, Node, Klist_node_by_node_cmp); |
0 | 80 return (*Klist)->Counter; |
81 } | |
82 | |
83 /* | |
84 * Remove data by Key | |
85 */ | |
86 void a_Klist_remove(Klist_t *Klist, int Key) | |
87 { | |
88 void *data; | |
89 | |
90 data = dList_find_sorted(Klist->List, INT2VOIDP(Key),Klist_node_by_key_cmp); | |
91 if (data) { | |
92 dList_remove(Klist->List, data); | |
93 dFree(data); | |
94 } | |
95 if (dList_length(Klist->List) == 0) | |
96 Klist->Clean = 1; | |
97 } | |
98 | |
99 /* | |
100 * Return the number of elements in the Klist | |
101 */ | |
102 int a_Klist_length(Klist_t *Klist) | |
103 { | |
104 return dList_length(Klist->List); | |
105 } | |
106 | |
107 /* | |
108 * Free a Klist | |
109 */ | |
110 void a_Klist_free(Klist_t **KlistPtr) | |
111 { | |
112 void *node; | |
113 Klist_t *Klist = *KlistPtr; | |
114 | |
115 if (!Klist) | |
116 return; | |
117 | |
118 while (dList_length(Klist->List) > 0) { | |
119 node = dList_nth_data(Klist->List, 0); | |
1079
aa1b2cac9edc
Fix a memory leak in a_Klist_free()
corvid <corvid@lavabit.com>
parents:
966
diff
changeset
|
120 dList_remove_fast(Klist->List, node); |
0 | 121 dFree(node); |
122 } | |
966 | 123 dList_free(Klist->List); |
0 | 124 dFree(Klist); |
125 *KlistPtr = NULL; | |
126 } | |
127 |