Merge lp:~jamesodhunt/libnih/iterators into lp:~upstart-devel/libnih/nih
- iterators
- Merge into nih
Status: | Work in progress |
---|---|
Proposed branch: | lp:~jamesodhunt/libnih/iterators |
Merge into: | lp:~upstart-devel/libnih/nih |
Diff against target: |
962 lines (+741/-8) (has conflicts) 11 files modified
ChangeLog (+13/-0) nih/hash.c (+62/-0) nih/hash.h (+7/-0) nih/list.c (+59/-0) nih/list.h (+18/-0) nih/tests/test_hash.c (+176/-2) nih/tests/test_list.c (+154/-3) nih/tests/test_tree.c (+170/-1) nih/tree.c (+62/-0) nih/tree.h (+18/-0) po/libnih.pot (+2/-2) Text conflict in ChangeLog |
To merge this branch: | bzr merge lp:~jamesodhunt/libnih/iterators |
Related bugs: |
Reviewer | Review Type | Date Requested | Status |
---|---|---|---|
Steve Langasek | Needs Fixing | ||
Review via email: mp+140151@code.launchpad.net |
Commit message
Description of the change
Unmerged revisions
- 1049. By James Hunt
-
* Changelog: Summary of new functions.
* nih/hash.c: New functions:
- nih_hash_foreach()
- nih_hash_count()
* nih/hash.h: Prototypes for new functions:
- nih_hash_foreach()
- nih_hash_count()
* nih/list.c: New functions:
- nih_list_foreach()
- nih_list_count()
* nih/list.h:
- Prototypes for new functions:
- nih_list_foreach()
- nih_list_count()
- New type: NihListHandler.
* nih/tree.c: New functions:
- nih_tree_foreach()
- nih_tree_count()
* nih/tree.h:
- Prototypes for new functions:
- nih_tree_foreach()
- nih_tree_count()
- New type: NihTreeHandler.
* nih/tests/test_hash. c:
- New functions:
- test_count()
- test_foreach_func () and supporting functions:
- hash_handler1()
- hash_handler2()
- hash_handler3()
- Updated main to call test_foreach_func() and test_count().
- Changed description for existing functions to make it clear that
NIH_HASH_FOREACH( ) is a macro.
* nih/tests/test_list. c:
- New functions:
- test_count()
- test_foreach_func() and supporting functions:
- list_handler1()
- list_handler2()
- list_handler3()
- Updated main to call test_foreach_func() and test_count().
- Changed description for existing functions to make it clear that
NIH_LIST_*() are macros.
* nih/tests/test_tree. c
- New functions:
- test_count()
- test_foreach_func () and supporting functions:
- tree_handler1()
- tree_handler2()
- tree_handler3()
- Updated main to call test_foreach_func() and test_count().
- Changed description for existing functions to make it clear that
NIH_TREE_FOREACH_ *() are macros.
Preview Diff
1 | === modified file 'ChangeLog' | |||
2 | --- ChangeLog 2011-09-01 18:41:03 +0000 | |||
3 | +++ ChangeLog 2012-12-17 09:27:29 +0000 | |||
4 | @@ -1,3 +1,4 @@ | |||
5 | 1 | <<<<<<< TREE | ||
6 | 1 | 2011-08-31 James Hunt <james.hunt@ubuntu.com> | 2 | 2011-08-31 James Hunt <james.hunt@ubuntu.com> |
7 | 2 | 3 | ||
8 | 3 | * nih-dbus-tool/tests/test_com.netsplit.Nih.Test_object.c | 4 | * nih-dbus-tool/tests/test_com.netsplit.Nih.Test_object.c |
9 | @@ -33,6 +34,18 @@ | |||
10 | 33 | a single slash (LP:#777097). | 34 | a single slash (LP:#777097). |
11 | 34 | * nih/tests/test_watch.c: Added explicit test for watch on a file. | 35 | * nih/tests/test_watch.c: Added explicit test for watch on a file. |
12 | 35 | 36 | ||
13 | 37 | ======= | ||
14 | 38 | 2011-05-08 James Hunt <james.hunt@ubuntu.com> | ||
15 | 39 | |||
16 | 40 | * New functions: | ||
17 | 41 | - nih_list_foreach() | ||
18 | 42 | - nih_hash_foreach() | ||
19 | 43 | - nih_tree_foreach() | ||
20 | 44 | - nih_list_count() | ||
21 | 45 | - nih_hash_count() | ||
22 | 46 | - nih_tree_count() | ||
23 | 47 | |||
24 | 48 | >>>>>>> MERGE-SOURCE | ||
25 | 36 | 2010-12-23 Scott James Remnant <scott@netsplit.com> | 49 | 2010-12-23 Scott James Remnant <scott@netsplit.com> |
26 | 37 | 50 | ||
27 | 38 | * configure.ac: Bump version to 1.0.4 | 51 | * configure.ac: Bump version to 1.0.4 |
28 | 39 | 52 | ||
29 | === modified file 'nih/hash.c' | |||
30 | --- nih/hash.c 2009-06-23 09:29:37 +0000 | |||
31 | +++ nih/hash.c 2012-12-17 09:27:29 +0000 | |||
32 | @@ -397,3 +397,65 @@ | |||
33 | 397 | 397 | ||
34 | 398 | return strcmp (key1, key2); | 398 | return strcmp (key1, key2); |
35 | 399 | } | 399 | } |
36 | 400 | |||
37 | 401 | /** | ||
38 | 402 | * nih_hash_foreach: | ||
39 | 403 | * | ||
40 | 404 | * @hash: hash, | ||
41 | 405 | * @len: optional output parameter that will contain count of hash entries, | ||
42 | 406 | * @handler: optional function called for each hash entry, | ||
43 | 407 | * @data: optional data to pass to handler along with hash entry. | ||
44 | 408 | * | ||
45 | 409 | * Iterate over specified hash. | ||
46 | 410 | * | ||
47 | 411 | * One of @len or @handler may be NULL. | ||
48 | 412 | * If @handler is NULL, count of hash entries will still be returned in @len. | ||
49 | 413 | * If @handler returns 1, @len will be set to the number of hash entries | ||
50 | 414 | * processed successfully up to that point. | ||
51 | 415 | * | ||
52 | 416 | * Returns 0 on success (and when both @len and @handler are NULL), | ||
53 | 417 | * or -1 if handler returns an error. | ||
54 | 418 | **/ | ||
55 | 419 | int | ||
56 | 420 | nih_hash_foreach (const NihHash *hash, size_t *len, | ||
57 | 421 | NihListHandler handler, void *data) | ||
58 | 422 | { | ||
59 | 423 | int ret; | ||
60 | 424 | |||
61 | 425 | nih_assert (hash); | ||
62 | 426 | |||
63 | 427 | if (len) *len = 0; | ||
64 | 428 | |||
65 | 429 | if (!len && !handler) return 0; | ||
66 | 430 | |||
67 | 431 | NIH_HASH_FOREACH (hash, iter) { | ||
68 | 432 | if (handler) { | ||
69 | 433 | ret = handler (iter, data); | ||
70 | 434 | if (ret == FALSE) return -1; | ||
71 | 435 | } | ||
72 | 436 | if (len) ++*len; | ||
73 | 437 | } | ||
74 | 438 | |||
75 | 439 | return 0; | ||
76 | 440 | } | ||
77 | 441 | |||
78 | 442 | /** | ||
79 | 443 | * nih_hash_count: | ||
80 | 444 | * | ||
81 | 445 | * @hash: hash. | ||
82 | 446 | * | ||
83 | 447 | * Returns count of number of entries in @hash. | ||
84 | 448 | **/ | ||
85 | 449 | size_t | ||
86 | 450 | nih_hash_count (const NihHash *hash) | ||
87 | 451 | { | ||
88 | 452 | size_t len = 0; | ||
89 | 453 | int ret; | ||
90 | 454 | |||
91 | 455 | nih_assert (hash); | ||
92 | 456 | |||
93 | 457 | ret = nih_hash_foreach (hash, &len, NULL, NULL); | ||
94 | 458 | |||
95 | 459 | return (ret == -1 ? 0 : len); | ||
96 | 460 | } | ||
97 | 461 | |||
98 | 400 | 462 | ||
99 | === modified file 'nih/hash.h' | |||
100 | --- nih/hash.h 2011-01-06 09:28:39 +0000 | |||
101 | +++ nih/hash.h 2012-12-17 09:27:29 +0000 | |||
102 | @@ -217,6 +217,13 @@ | |||
103 | 217 | uint32_t nih_hash_string_hash (const char *key); | 217 | uint32_t nih_hash_string_hash (const char *key); |
104 | 218 | int nih_hash_string_cmp (const char *key1, const char *key2); | 218 | int nih_hash_string_cmp (const char *key1, const char *key2); |
105 | 219 | 219 | ||
106 | 220 | int nih_hash_foreach (const NihHash *hash, size_t *len, | ||
107 | 221 | NihListHandler handler, void *data) | ||
108 | 222 | __attribute__((unused)); | ||
109 | 223 | |||
110 | 224 | size_t nih_hash_count (const NihHash *hash) | ||
111 | 225 | __attribute__((warn_unused_result, unused)); | ||
112 | 226 | |||
113 | 220 | NIH_END_EXTERN | 227 | NIH_END_EXTERN |
114 | 221 | 228 | ||
115 | 222 | #endif /* NIH_HASH_H */ | 229 | #endif /* NIH_HASH_H */ |
116 | 223 | 230 | ||
117 | === modified file 'nih/list.c' | |||
118 | --- nih/list.c 2009-06-23 09:29:37 +0000 | |||
119 | +++ nih/list.c 2012-12-17 09:27:29 +0000 | |||
120 | @@ -249,3 +249,62 @@ | |||
121 | 249 | 249 | ||
122 | 250 | return 0; | 250 | return 0; |
123 | 251 | } | 251 | } |
124 | 252 | |||
125 | 253 | /** | ||
126 | 254 | * nih_list_foreach: | ||
127 | 255 | * @list: list, | ||
128 | 256 | * @len: optional output parameter that will contain length of list, | ||
129 | 257 | * @handler: optional function called for each list entry, | ||
130 | 258 | * @data: optional data to pass to handler along with list entry. | ||
131 | 259 | * | ||
132 | 260 | * Iterate over specified list. | ||
133 | 261 | * | ||
134 | 262 | * One of @len or @handler may be NULL. | ||
135 | 263 | * If @handler is NULL, list length will still be returned in @len. | ||
136 | 264 | * If @handler returns 1, @len will be set to the number of list entries | ||
137 | 265 | * processed successfully up to that point. | ||
138 | 266 | * | ||
139 | 267 | * Returns 0 on success (and when both @len and @handler are NULL), | ||
140 | 268 | * or -1 if handler returns an error. | ||
141 | 269 | **/ | ||
142 | 270 | int | ||
143 | 271 | nih_list_foreach (const NihList *list, size_t *len, | ||
144 | 272 | NihListHandler handler, void *data) | ||
145 | 273 | { | ||
146 | 274 | int ret; | ||
147 | 275 | |||
148 | 276 | nih_assert (list); | ||
149 | 277 | |||
150 | 278 | if (len) *len = 0; | ||
151 | 279 | |||
152 | 280 | if (!len && !handler) return 0; | ||
153 | 281 | |||
154 | 282 | NIH_LIST_FOREACH (list, iter) { | ||
155 | 283 | if (handler) { | ||
156 | 284 | ret = handler (iter, data); | ||
157 | 285 | if (ret == FALSE) return -1; | ||
158 | 286 | } | ||
159 | 287 | if (len) ++*len; | ||
160 | 288 | } | ||
161 | 289 | |||
162 | 290 | return 0; | ||
163 | 291 | } | ||
164 | 292 | |||
165 | 293 | /** | ||
166 | 294 | * nih_list_count: | ||
167 | 295 | * @list: list. | ||
168 | 296 | * | ||
169 | 297 | * Returns count of number of entries in @list. | ||
170 | 298 | **/ | ||
171 | 299 | size_t | ||
172 | 300 | nih_list_count (const NihList *list) | ||
173 | 301 | { | ||
174 | 302 | size_t len = 0; | ||
175 | 303 | int ret; | ||
176 | 304 | |||
177 | 305 | nih_assert (list); | ||
178 | 306 | |||
179 | 307 | ret = nih_list_foreach (list, &len, NULL, NULL); | ||
180 | 308 | |||
181 | 309 | return (ret == -1 ? 0 : len); | ||
182 | 310 | } | ||
183 | 252 | 311 | ||
184 | === modified file 'nih/list.h' | |||
185 | --- nih/list.h 2011-01-06 09:28:39 +0000 | |||
186 | +++ nih/list.h 2012-12-17 09:27:29 +0000 | |||
187 | @@ -110,6 +110,17 @@ | |||
188 | 110 | }; | 110 | }; |
189 | 111 | } NihListEntry; | 111 | } NihListEntry; |
190 | 112 | 112 | ||
191 | 113 | /** | ||
192 | 114 | * NihListHandler: | ||
193 | 115 | * @entry: list entry being visited, | ||
194 | 116 | * @data: data pointer. | ||
195 | 117 | * | ||
196 | 118 | * A list handler is a function called for each list entry | ||
197 | 119 | * when iterating over a list. | ||
198 | 120 | * | ||
199 | 121 | * Returns: TRUE if list entry process correctly, else FALSE. | ||
200 | 122 | **/ | ||
201 | 123 | typedef int (*NihListHandler) (NihList *entry, void *data); | ||
202 | 113 | 124 | ||
203 | 114 | /** | 125 | /** |
204 | 115 | * NIH_LIST_EMPTY: | 126 | * NIH_LIST_EMPTY: |
205 | @@ -208,6 +219,13 @@ | |||
206 | 208 | NihList * nih_list_remove (NihList *entry); | 219 | NihList * nih_list_remove (NihList *entry); |
207 | 209 | int nih_list_destroy (NihList *entry); | 220 | int nih_list_destroy (NihList *entry); |
208 | 210 | 221 | ||
209 | 222 | int nih_list_foreach (const NihList *list, size_t *len, | ||
210 | 223 | NihListHandler handler, void *data) | ||
211 | 224 | __attribute__((unused)); | ||
212 | 225 | |||
213 | 226 | size_t nih_list_count (const NihList *list) | ||
214 | 227 | __attribute__((warn_unused_result, unused)); | ||
215 | 228 | |||
216 | 211 | NIH_END_EXTERN | 229 | NIH_END_EXTERN |
217 | 212 | 230 | ||
218 | 213 | #endif /* NIH_LIST_H */ | 231 | #endif /* NIH_LIST_H */ |
219 | 214 | 232 | ||
220 | === modified file 'nih/tests/test_hash.c' | |||
221 | --- nih/tests/test_hash.c 2009-06-23 09:29:37 +0000 | |||
222 | +++ nih/tests/test_hash.c 2012-12-17 09:27:29 +0000 | |||
223 | @@ -25,6 +25,11 @@ | |||
224 | 25 | #include <nih/alloc.h> | 25 | #include <nih/alloc.h> |
225 | 26 | #include <nih/list.h> | 26 | #include <nih/list.h> |
226 | 27 | #include <nih/hash.h> | 27 | #include <nih/hash.h> |
227 | 28 | #include <nih/string.h> | ||
228 | 29 | |||
229 | 30 | #define HASH_HANDLER_DATA_VALUE 42 | ||
230 | 31 | #define LIST_ENTRIES 4 | ||
231 | 32 | #define ERROR_ON_ENTRY 3 | ||
232 | 28 | 33 | ||
233 | 29 | 34 | ||
234 | 30 | typedef struct hash_entry { | 35 | typedef struct hash_entry { |
235 | @@ -514,7 +519,7 @@ | |||
236 | 514 | * in the hash in the order we expect them to come out in, but add | 519 | * in the hash in the order we expect them to come out in, but add |
237 | 515 | * them in a different order for sanity. | 520 | * them in a different order for sanity. |
238 | 516 | */ | 521 | */ |
240 | 517 | TEST_FUNCTION ("NIH_HASH_FOREACH"); | 522 | TEST_FUNCTION ("NIH_HASH_FOREACH macro"); |
241 | 518 | hash = nih_hash_string_new (NULL, 0); | 523 | hash = nih_hash_string_new (NULL, 0); |
242 | 519 | entry0 = entry[2] = new_entry (hash, "entry 1"); | 524 | entry0 = entry[2] = new_entry (hash, "entry 1"); |
243 | 520 | entry1 = entry[1] = new_entry (hash, "entry 2"); | 525 | entry1 = entry[1] = new_entry (hash, "entry 2"); |
244 | @@ -542,6 +547,173 @@ | |||
245 | 542 | nih_free (hash); | 547 | nih_free (hash); |
246 | 543 | } | 548 | } |
247 | 544 | 549 | ||
248 | 550 | int | ||
249 | 551 | hash_handler1 (NihList *entry, int *data) | ||
250 | 552 | { | ||
251 | 553 | TEST_NE_P (entry, NULL); | ||
252 | 554 | TEST_NE_P (data, NULL); | ||
253 | 555 | |||
254 | 556 | TEST_EQ (*data, HASH_HANDLER_DATA_VALUE); | ||
255 | 557 | |||
256 | 558 | return TRUE; | ||
257 | 559 | } | ||
258 | 560 | |||
259 | 561 | int | ||
260 | 562 | hash_handler2 (NihList *entry, int *data) | ||
261 | 563 | { | ||
262 | 564 | static size_t i = 0; | ||
263 | 565 | |||
264 | 566 | TEST_NE_P (entry, NULL); | ||
265 | 567 | TEST_NE_P (data, NULL); | ||
266 | 568 | |||
267 | 569 | ++i; | ||
268 | 570 | *data = i; | ||
269 | 571 | |||
270 | 572 | return TRUE; | ||
271 | 573 | } | ||
272 | 574 | |||
273 | 575 | int | ||
274 | 576 | hash_handler3 (NihList *entry, void *data) | ||
275 | 577 | { | ||
276 | 578 | static size_t i = 0; | ||
277 | 579 | |||
278 | 580 | TEST_NE_P (entry, NULL); | ||
279 | 581 | TEST_NE_P (data, NULL); | ||
280 | 582 | |||
281 | 583 | ++i; | ||
282 | 584 | *(int *)data = i; | ||
283 | 585 | |||
284 | 586 | if (i == ERROR_ON_ENTRY) | ||
285 | 587 | return FALSE; | ||
286 | 588 | |||
287 | 589 | return TRUE; | ||
288 | 590 | } | ||
289 | 591 | |||
290 | 592 | void | ||
291 | 593 | test_foreach_func (void) | ||
292 | 594 | { | ||
293 | 595 | NihHash *hash; | ||
294 | 596 | NihList *entry[LIST_ENTRIES]; | ||
295 | 597 | NihList *entry0, *entry1, *entry2, *entry3; | ||
296 | 598 | size_t len = 0; | ||
297 | 599 | int data1 = HASH_HANDLER_DATA_VALUE; | ||
298 | 600 | size_t data2 = 0; | ||
299 | 601 | int ret; | ||
300 | 602 | |||
301 | 603 | TEST_FUNCTION ("nih_hash_foreach"); | ||
302 | 604 | |||
303 | 605 | hash = nih_hash_string_new (NULL, 0); | ||
304 | 606 | TEST_NE_P (hash, NULL); | ||
305 | 607 | |||
306 | 608 | |||
307 | 609 | TEST_FEATURE ("with no handler, length or data params"); | ||
308 | 610 | TEST_EQ (nih_hash_foreach (hash, NULL, NULL, NULL), 0); | ||
309 | 611 | |||
310 | 612 | |||
311 | 613 | TEST_FEATURE ("with length param, but no handler"); | ||
312 | 614 | |||
313 | 615 | ret = nih_hash_foreach (hash, &len, NULL, NULL); | ||
314 | 616 | TEST_EQ (ret, 0); | ||
315 | 617 | TEST_EQ (len, 0); | ||
316 | 618 | |||
317 | 619 | |||
318 | 620 | TEST_FEATURE ("with data and handler reading a value, but no len"); | ||
319 | 621 | |||
320 | 622 | entry0 = entry[0] = new_entry (hash, "entry 1"); | ||
321 | 623 | entry1 = entry[1] = new_entry (hash, "entry 2"); | ||
322 | 624 | entry2 = entry[2] = new_entry (hash, "entry 3"); | ||
323 | 625 | entry3 = entry[3] = new_entry (hash, "entry 4"); | ||
324 | 626 | |||
325 | 627 | nih_hash_add (hash, entry0); | ||
326 | 628 | nih_hash_add (hash, entry1); | ||
327 | 629 | nih_hash_add (hash, entry2); | ||
328 | 630 | nih_hash_add (hash, entry3); | ||
329 | 631 | |||
330 | 632 | ret = nih_hash_foreach (hash, NULL, | ||
331 | 633 | (NihListHandler)hash_handler1, &data1); | ||
332 | 634 | |||
333 | 635 | TEST_EQ (ret, 0); | ||
334 | 636 | TEST_EQ (data1, HASH_HANDLER_DATA_VALUE); | ||
335 | 637 | |||
336 | 638 | |||
337 | 639 | TEST_FEATURE ("with len, data and handler reading a value"); | ||
338 | 640 | |||
339 | 641 | ret = nih_hash_foreach (hash, &len, | ||
340 | 642 | (NihListHandler)hash_handler1, &data1); | ||
341 | 643 | |||
342 | 644 | TEST_EQ (ret, 0); | ||
343 | 645 | TEST_EQ (data1, HASH_HANDLER_DATA_VALUE); | ||
344 | 646 | TEST_EQ (len, LIST_ENTRIES); | ||
345 | 647 | |||
346 | 648 | |||
347 | 649 | TEST_FEATURE ("with len, data and hander changing a value"); | ||
348 | 650 | |||
349 | 651 | len = 0; | ||
350 | 652 | data2 = 0; | ||
351 | 653 | ret = nih_hash_foreach (hash, &len, | ||
352 | 654 | (NihListHandler)hash_handler2, &data2); | ||
353 | 655 | |||
354 | 656 | TEST_EQ (ret, 0); | ||
355 | 657 | TEST_EQ (len, LIST_ENTRIES); | ||
356 | 658 | TEST_EQ (data2, LIST_ENTRIES); | ||
357 | 659 | |||
358 | 660 | |||
359 | 661 | TEST_FEATURE ("with handler returning error"); | ||
360 | 662 | |||
361 | 663 | len = 0; | ||
362 | 664 | data2 = 0; | ||
363 | 665 | ret = nih_hash_foreach (hash, &len, | ||
364 | 666 | (NihListHandler)hash_handler3, &data2); | ||
365 | 667 | TEST_EQ (ret, -1); | ||
366 | 668 | TEST_EQ (len, ERROR_ON_ENTRY-1); | ||
367 | 669 | } | ||
368 | 670 | |||
369 | 671 | void | ||
370 | 672 | test_count (void) | ||
371 | 673 | { | ||
372 | 674 | NihHash *hash; | ||
373 | 675 | NihList *entry[LIST_ENTRIES]; | ||
374 | 676 | nih_local char *key; | ||
375 | 677 | NihList *e; | ||
376 | 678 | size_t i; | ||
377 | 679 | |||
378 | 680 | TEST_FUNCTION ("nih_hash_count"); | ||
379 | 681 | |||
380 | 682 | hash = nih_hash_string_new (NULL, 0); | ||
381 | 683 | TEST_NE_P (hash, NULL); | ||
382 | 684 | |||
383 | 685 | i = 0; | ||
384 | 686 | TEST_FEATURE ("with no initial entries"); | ||
385 | 687 | TEST_EQ (nih_hash_count (hash), i); | ||
386 | 688 | |||
387 | 689 | entry[0] = new_entry (hash, "entry 1"); | ||
388 | 690 | entry[1] = new_entry (hash, "entry 2"); | ||
389 | 691 | entry[2] = new_entry (hash, "entry 3"); | ||
390 | 692 | entry[3] = new_entry (hash, "entry 4"); | ||
391 | 693 | |||
392 | 694 | TEST_FEATURE ("with increasing number of entries"); | ||
393 | 695 | |||
394 | 696 | for (i=0; i < LIST_ENTRIES; ++i) { | ||
395 | 697 | nih_hash_add (hash, entry[i]); | ||
396 | 698 | TEST_EQ (nih_hash_count (hash), i+1); | ||
397 | 699 | } | ||
398 | 700 | |||
399 | 701 | TEST_FEATURE ("with decreasing number of entries"); | ||
400 | 702 | |||
401 | 703 | for (i=LIST_ENTRIES; i > 0; --i) { | ||
402 | 704 | key = nih_sprintf (NULL, "entry %d", i); | ||
403 | 705 | TEST_NE_P (key, NULL); | ||
404 | 706 | |||
405 | 707 | e = nih_hash_lookup (hash, key); | ||
406 | 708 | TEST_NE_P (e, NULL); | ||
407 | 709 | nih_free (nih_list_remove (e)); | ||
408 | 710 | TEST_EQ (nih_hash_count (hash), i-1); | ||
409 | 711 | } | ||
410 | 712 | |||
411 | 713 | TEST_FEATURE ("with no entries"); | ||
412 | 714 | TEST_EQ (nih_hash_count (hash), 0); | ||
413 | 715 | } | ||
414 | 716 | |||
415 | 545 | void | 717 | void |
416 | 546 | test_foreach_safe (void) | 718 | test_foreach_safe (void) |
417 | 547 | { | 719 | { |
418 | @@ -553,7 +725,7 @@ | |||
419 | 553 | * order, visiting each entry in each bin; and that it's safe to | 725 | * order, visiting each entry in each bin; and that it's safe to |
420 | 554 | * remove the entries while doing so. | 726 | * remove the entries while doing so. |
421 | 555 | */ | 727 | */ |
423 | 556 | TEST_FUNCTION ("NIH_HASH_FOREACH_SAFE"); | 728 | TEST_FUNCTION ("NIH_HASH_FOREACH_SAFE macro"); |
424 | 557 | hash = nih_hash_string_new (NULL, 0); | 729 | hash = nih_hash_string_new (NULL, 0); |
425 | 558 | entry0 = entry[2] = new_entry (hash, "entry 1"); | 730 | entry0 = entry[2] = new_entry (hash, "entry 1"); |
426 | 559 | entry1 = entry[1] = new_entry (hash, "entry 2"); | 731 | entry1 = entry[1] = new_entry (hash, "entry 2"); |
427 | @@ -619,6 +791,8 @@ | |||
428 | 619 | test_lookup (); | 791 | test_lookup (); |
429 | 620 | test_foreach (); | 792 | test_foreach (); |
430 | 621 | test_foreach_safe (); | 793 | test_foreach_safe (); |
431 | 794 | test_foreach_func (); | ||
432 | 795 | test_count (); | ||
433 | 622 | test_string_key (); | 796 | test_string_key (); |
434 | 623 | 797 | ||
435 | 624 | return 0; | 798 | return 0; |
436 | 625 | 799 | ||
437 | === modified file 'nih/tests/test_list.c' | |||
438 | --- nih/tests/test_list.c 2009-06-23 09:29:37 +0000 | |||
439 | +++ nih/tests/test_list.c 2012-12-17 09:27:29 +0000 | |||
440 | @@ -25,6 +25,9 @@ | |||
441 | 25 | #include <nih/alloc.h> | 25 | #include <nih/alloc.h> |
442 | 26 | #include <nih/list.h> | 26 | #include <nih/list.h> |
443 | 27 | 27 | ||
444 | 28 | #define LIST_HANDLER_DATA_VALUE 42 | ||
445 | 29 | #define LIST_ENTRIES 3 | ||
446 | 30 | #define ERROR_ON_ENTRY 2 | ||
447 | 28 | 31 | ||
448 | 29 | void | 32 | void |
449 | 30 | test_init (void) | 33 | test_init (void) |
450 | @@ -251,7 +254,7 @@ | |||
451 | 251 | { | 254 | { |
452 | 252 | NihList *list, *entry; | 255 | NihList *list, *entry; |
453 | 253 | 256 | ||
455 | 254 | TEST_FUNCTION ("NIH_LIST_EMPTY"); | 257 | TEST_FUNCTION ("NIH_LIST_EMPTY macro"); |
456 | 255 | 258 | ||
457 | 256 | /* Check that NIH_LIST_EMPTY is TRUE on an empty list */ | 259 | /* Check that NIH_LIST_EMPTY is TRUE on an empty list */ |
458 | 257 | TEST_FEATURE ("with empty list"); | 260 | TEST_FEATURE ("with empty list"); |
459 | @@ -281,7 +284,7 @@ | |||
460 | 281 | /* Check that NIH_LIST_FOREACH iterates the list correctly in | 284 | /* Check that NIH_LIST_FOREACH iterates the list correctly in |
461 | 282 | * order, visiting each entry. | 285 | * order, visiting each entry. |
462 | 283 | */ | 286 | */ |
464 | 284 | TEST_FUNCTION ("NIH_LIST_FOREACH"); | 287 | TEST_FUNCTION ("NIH_LIST_FOREACH macro"); |
465 | 285 | list = nih_list_new (NULL); | 288 | list = nih_list_new (NULL); |
466 | 286 | entry[0] = nih_list_add (list, nih_list_new (NULL)); | 289 | entry[0] = nih_list_add (list, nih_list_new (NULL)); |
467 | 287 | entry[1] = nih_list_add (list, nih_list_new (NULL)); | 290 | entry[1] = nih_list_add (list, nih_list_new (NULL)); |
468 | @@ -306,13 +309,159 @@ | |||
469 | 306 | nih_free (entry[2]); | 309 | nih_free (entry[2]); |
470 | 307 | } | 310 | } |
471 | 308 | 311 | ||
472 | 312 | int | ||
473 | 313 | list_handler1 (NihList *entry, int *data) | ||
474 | 314 | { | ||
475 | 315 | TEST_NE_P (entry, NULL); | ||
476 | 316 | TEST_NE_P (data, NULL); | ||
477 | 317 | |||
478 | 318 | TEST_EQ (*data, LIST_HANDLER_DATA_VALUE); | ||
479 | 319 | |||
480 | 320 | return TRUE; | ||
481 | 321 | } | ||
482 | 322 | |||
483 | 323 | int | ||
484 | 324 | list_handler2 (NihList *entry, int *data) | ||
485 | 325 | { | ||
486 | 326 | static size_t i = 0; | ||
487 | 327 | |||
488 | 328 | TEST_NE_P (entry, NULL); | ||
489 | 329 | TEST_NE_P (data, NULL); | ||
490 | 330 | |||
491 | 331 | ++i; | ||
492 | 332 | *data = i; | ||
493 | 333 | |||
494 | 334 | return TRUE; | ||
495 | 335 | } | ||
496 | 336 | |||
497 | 337 | int | ||
498 | 338 | list_handler3 (NihList *entry, void *data) | ||
499 | 339 | { | ||
500 | 340 | static size_t i = 0; | ||
501 | 341 | |||
502 | 342 | TEST_NE_P (entry, NULL); | ||
503 | 343 | TEST_NE_P (data, NULL); | ||
504 | 344 | |||
505 | 345 | ++i; | ||
506 | 346 | *(int *)data = i; | ||
507 | 347 | |||
508 | 348 | if (i == ERROR_ON_ENTRY) | ||
509 | 349 | return FALSE; | ||
510 | 350 | |||
511 | 351 | return TRUE; | ||
512 | 352 | } | ||
513 | 353 | |||
514 | 354 | void | ||
515 | 355 | test_foreach_func (void) | ||
516 | 356 | { | ||
517 | 357 | NihList *list, *entry[LIST_ENTRIES]; | ||
518 | 358 | size_t len = 0; | ||
519 | 359 | int data1 = LIST_HANDLER_DATA_VALUE; | ||
520 | 360 | size_t data2 = 0; | ||
521 | 361 | int ret; | ||
522 | 362 | |||
523 | 363 | TEST_FUNCTION ("nih_list_foreach"); | ||
524 | 364 | |||
525 | 365 | list = nih_list_new (NULL); | ||
526 | 366 | TEST_NE_P (list, NULL); | ||
527 | 367 | |||
528 | 368 | |||
529 | 369 | TEST_FEATURE ("with no handler, length or data params"); | ||
530 | 370 | |||
531 | 371 | ret = nih_list_foreach (list, NULL, NULL, NULL); | ||
532 | 372 | TEST_EQ (ret, 0); | ||
533 | 373 | |||
534 | 374 | TEST_FEATURE ("with length param, but no handler"); | ||
535 | 375 | ret = nih_list_foreach (list, &len, NULL, NULL); | ||
536 | 376 | TEST_EQ (ret, 0); | ||
537 | 377 | TEST_EQ (len, 0); | ||
538 | 378 | |||
539 | 379 | |||
540 | 380 | TEST_FEATURE ("with data and handler reading a value, but no len"); | ||
541 | 381 | |||
542 | 382 | entry[0] = nih_list_add (list, nih_list_new (NULL)); | ||
543 | 383 | entry[1] = nih_list_add (list, nih_list_new (NULL)); | ||
544 | 384 | entry[2] = nih_list_add (list, nih_list_new (NULL)); | ||
545 | 385 | |||
546 | 386 | ret = nih_list_foreach (list, NULL, | ||
547 | 387 | (NihListHandler)list_handler1, &data1); | ||
548 | 388 | |||
549 | 389 | TEST_EQ (ret, 0); | ||
550 | 390 | TEST_EQ (data1, LIST_HANDLER_DATA_VALUE); | ||
551 | 391 | |||
552 | 392 | |||
553 | 393 | TEST_FEATURE ("with len, data and handler reading a value"); | ||
554 | 394 | |||
555 | 395 | ret = nih_list_foreach (list, &len, | ||
556 | 396 | (NihListHandler)list_handler1, &data1); | ||
557 | 397 | |||
558 | 398 | TEST_EQ (ret, 0); | ||
559 | 399 | TEST_EQ (len, LIST_ENTRIES); | ||
560 | 400 | TEST_EQ (data1, LIST_HANDLER_DATA_VALUE); | ||
561 | 401 | |||
562 | 402 | |||
563 | 403 | TEST_FEATURE ("with len, data and hander changing a value"); | ||
564 | 404 | |||
565 | 405 | len = 0; | ||
566 | 406 | data2 = 0; | ||
567 | 407 | ret = nih_list_foreach (list, &len, | ||
568 | 408 | (NihListHandler)list_handler2, &data2); | ||
569 | 409 | TEST_EQ (ret, 0); | ||
570 | 410 | TEST_EQ (len, LIST_ENTRIES); | ||
571 | 411 | TEST_EQ (data2, LIST_ENTRIES); | ||
572 | 412 | |||
573 | 413 | |||
574 | 414 | TEST_FEATURE ("with handler returning error"); | ||
575 | 415 | |||
576 | 416 | len = 0; | ||
577 | 417 | data2 = 0; | ||
578 | 418 | ret = nih_list_foreach (list, &len, | ||
579 | 419 | (NihListHandler)list_handler3, &data2); | ||
580 | 420 | TEST_EQ (ret, -1); | ||
581 | 421 | TEST_EQ (len, ERROR_ON_ENTRY-1); | ||
582 | 422 | } | ||
583 | 423 | |||
584 | 424 | void | ||
585 | 425 | test_count (void) | ||
586 | 426 | { | ||
587 | 427 | NihList *list, *entry[3]; | ||
588 | 428 | size_t i; | ||
589 | 429 | |||
590 | 430 | TEST_FUNCTION ("nih_list_count"); | ||
591 | 431 | |||
592 | 432 | list = nih_list_new (NULL); | ||
593 | 433 | TEST_NE_P (list, NULL); | ||
594 | 434 | |||
595 | 435 | TEST_FEATURE ("with no initial entries"); | ||
596 | 436 | TEST_EQ (nih_list_count (list), 0); | ||
597 | 437 | TEST_EQ (NIH_LIST_EMPTY (list), TRUE); | ||
598 | 438 | |||
599 | 439 | TEST_FEATURE ("with increasing number of entries"); | ||
600 | 440 | for (i=0; i < LIST_ENTRIES; ++i) { | ||
601 | 441 | entry[i] = nih_list_add (list, nih_list_new (NULL)); | ||
602 | 442 | TEST_EQ (nih_list_count (list), i+1); | ||
603 | 443 | } | ||
604 | 444 | |||
605 | 445 | TEST_FEATURE ("with decreasing number of entries"); | ||
606 | 446 | |||
607 | 447 | for (i=LIST_ENTRIES; i > 0; --i) { | ||
608 | 448 | nih_free (nih_list_remove (list->next)); | ||
609 | 449 | TEST_EQ (nih_list_count (list), i-1); | ||
610 | 450 | } | ||
611 | 451 | |||
612 | 452 | TEST_FEATURE ("with no entries"); | ||
613 | 453 | TEST_EQ (nih_list_count (list), 0); | ||
614 | 454 | TEST_EQ (NIH_LIST_EMPTY (list), TRUE); | ||
615 | 455 | |||
616 | 456 | } | ||
617 | 457 | |||
618 | 309 | void | 458 | void |
619 | 310 | test_foreach_safe (void) | 459 | test_foreach_safe (void) |
620 | 311 | { | 460 | { |
621 | 312 | NihList *list, *entry[3]; | 461 | NihList *list, *entry[3]; |
622 | 313 | int i; | 462 | int i; |
623 | 314 | 463 | ||
625 | 315 | TEST_FUNCTION ("NIH_LIST_FOREACH_SAFE"); | 464 | TEST_FUNCTION ("NIH_LIST_FOREACH_SAFE macro"); |
626 | 316 | 465 | ||
627 | 317 | /* Check that NIH_LIST_FOREACH_SAFE iterates the list correctly in | 466 | /* Check that NIH_LIST_FOREACH_SAFE iterates the list correctly in |
628 | 318 | * order, visiting each entry. | 467 | * order, visiting each entry. |
629 | @@ -503,6 +652,8 @@ | |||
630 | 503 | test_empty (); | 652 | test_empty (); |
631 | 504 | test_foreach (); | 653 | test_foreach (); |
632 | 505 | test_foreach_safe (); | 654 | test_foreach_safe (); |
633 | 655 | test_foreach_func (); | ||
634 | 656 | test_count (); | ||
635 | 506 | test_remove (); | 657 | test_remove (); |
636 | 507 | test_destroy (); | 658 | test_destroy (); |
637 | 508 | 659 | ||
638 | 509 | 660 | ||
639 | === modified file 'nih/tests/test_tree.c' | |||
640 | --- nih/tests/test_tree.c 2009-06-23 09:29:37 +0000 | |||
641 | +++ nih/tests/test_tree.c 2012-12-17 09:27:29 +0000 | |||
642 | @@ -25,6 +25,9 @@ | |||
643 | 25 | #include <nih/alloc.h> | 25 | #include <nih/alloc.h> |
644 | 26 | #include <nih/tree.h> | 26 | #include <nih/tree.h> |
645 | 27 | 27 | ||
646 | 28 | #define TREE_HANDLER_DATA_VALUE 42 | ||
647 | 29 | #define NODE_COUNT 4 | ||
648 | 30 | #define ERROR_ON_NODE 3 | ||
649 | 28 | 31 | ||
650 | 29 | void | 32 | void |
651 | 30 | test_init (void) | 33 | test_init (void) |
652 | @@ -508,7 +511,7 @@ | |||
653 | 508 | NihTree *node[12], *expect[13]; | 511 | NihTree *node[12], *expect[13]; |
654 | 509 | int i; | 512 | int i; |
655 | 510 | 513 | ||
657 | 511 | TEST_FUNCTION ("NIH_TREE_FOREACH"); | 514 | TEST_FUNCTION ("NIH_TREE_FOREACH macro"); |
658 | 512 | for (i = 0; i < 12; i++) | 515 | for (i = 0; i < 12; i++) |
659 | 513 | node[i] = nih_tree_new (NULL); | 516 | node[i] = nih_tree_new (NULL); |
660 | 514 | 517 | ||
661 | @@ -589,6 +592,170 @@ | |||
662 | 589 | nih_free (node[i]); | 592 | nih_free (node[i]); |
663 | 590 | } | 593 | } |
664 | 591 | 594 | ||
665 | 595 | int | ||
666 | 596 | tree_handler1 (NihTree *node, void *data) | ||
667 | 597 | { | ||
668 | 598 | TEST_NE_P (node, NULL); | ||
669 | 599 | TEST_NE_P (data, NULL); | ||
670 | 600 | |||
671 | 601 | TEST_EQ (*(int *)data, TREE_HANDLER_DATA_VALUE); | ||
672 | 602 | |||
673 | 603 | return TRUE; | ||
674 | 604 | } | ||
675 | 605 | |||
676 | 606 | int | ||
677 | 607 | tree_handler2 (NihTree *node, void *data) | ||
678 | 608 | { | ||
679 | 609 | static size_t count = 0; | ||
680 | 610 | |||
681 | 611 | TEST_NE_P (node, NULL); | ||
682 | 612 | TEST_NE_P (data, NULL); | ||
683 | 613 | |||
684 | 614 | ++count; | ||
685 | 615 | *(int *)data = count; | ||
686 | 616 | |||
687 | 617 | return TRUE; | ||
688 | 618 | } | ||
689 | 619 | |||
690 | 620 | int | ||
691 | 621 | tree_handler3 (NihTree *node, void *data) | ||
692 | 622 | { | ||
693 | 623 | static size_t i = 0; | ||
694 | 624 | |||
695 | 625 | TEST_NE_P (node, NULL); | ||
696 | 626 | TEST_NE_P (data, NULL); | ||
697 | 627 | |||
698 | 628 | ++i; | ||
699 | 629 | *(int *)data = i; | ||
700 | 630 | |||
701 | 631 | if (i == ERROR_ON_NODE) | ||
702 | 632 | return FALSE; | ||
703 | 633 | |||
704 | 634 | return TRUE; | ||
705 | 635 | } | ||
706 | 636 | |||
707 | 637 | void | ||
708 | 638 | test_foreach_func (void) | ||
709 | 639 | { | ||
710 | 640 | NihTree *tree, *node1, *node2, *node3; | ||
711 | 641 | int data1 = TREE_HANDLER_DATA_VALUE; | ||
712 | 642 | size_t data2 = 0; | ||
713 | 643 | int ret; | ||
714 | 644 | size_t len; | ||
715 | 645 | |||
716 | 646 | TEST_FUNCTION ("nih_tree_foreach function"); | ||
717 | 647 | |||
718 | 648 | tree = nih_tree_new (NULL); | ||
719 | 649 | |||
720 | 650 | |||
721 | 651 | TEST_FEATURE ("with no handler, length or data params"); | ||
722 | 652 | TEST_EQ (nih_tree_foreach (tree, NULL, NULL, NULL), 0); | ||
723 | 653 | |||
724 | 654 | |||
725 | 655 | TEST_FEATURE ("with length param, but no handler"); | ||
726 | 656 | |||
727 | 657 | ret = nih_tree_foreach (tree, &len, NULL, NULL); | ||
728 | 658 | TEST_EQ (ret, 0); | ||
729 | 659 | TEST_EQ (len, 1); | ||
730 | 660 | |||
731 | 661 | node1 = nih_tree_new (tree); | ||
732 | 662 | node2 = nih_tree_new (tree); | ||
733 | 663 | node3 = nih_tree_new (tree); | ||
734 | 664 | |||
735 | 665 | nih_tree_add (tree, node1, NIH_TREE_LEFT); | ||
736 | 666 | ret = nih_tree_foreach (tree, &len, NULL, NULL); | ||
737 | 667 | TEST_EQ (ret, 0); | ||
738 | 668 | TEST_EQ (len, 2); | ||
739 | 669 | |||
740 | 670 | nih_tree_add (tree, node2, NIH_TREE_RIGHT); | ||
741 | 671 | ret = nih_tree_foreach (tree, &len, NULL, NULL); | ||
742 | 672 | TEST_EQ (ret, 0); | ||
743 | 673 | TEST_EQ (len, 3); | ||
744 | 674 | |||
745 | 675 | nih_tree_add (node1, node3, NIH_TREE_RIGHT); | ||
746 | 676 | |||
747 | 677 | ret = nih_tree_foreach (tree, &len, NULL, NULL); | ||
748 | 678 | TEST_EQ (ret, 0); | ||
749 | 679 | TEST_EQ (len, 4); | ||
750 | 680 | |||
751 | 681 | |||
752 | 682 | TEST_FEATURE ("with data and handler reading a value, but no len"); | ||
753 | 683 | |||
754 | 684 | ret = nih_tree_foreach (tree, NULL, | ||
755 | 685 | (NihTreeHandler)tree_handler1, &data1); | ||
756 | 686 | |||
757 | 687 | TEST_EQ (ret, 0); | ||
758 | 688 | TEST_EQ (data1, TREE_HANDLER_DATA_VALUE); | ||
759 | 689 | |||
760 | 690 | TEST_FEATURE ("with len, data and handler reading a value"); | ||
761 | 691 | |||
762 | 692 | ret = nih_tree_foreach (tree, &len, | ||
763 | 693 | (NihTreeHandler)tree_handler1, &data1); | ||
764 | 694 | |||
765 | 695 | TEST_EQ (ret, 0); | ||
766 | 696 | TEST_EQ (data1, TREE_HANDLER_DATA_VALUE); | ||
767 | 697 | TEST_EQ (len, NODE_COUNT); | ||
768 | 698 | |||
769 | 699 | TEST_FEATURE ("with len, data and handler changing a value"); | ||
770 | 700 | |||
771 | 701 | data2 = 0; | ||
772 | 702 | ret = nih_tree_foreach (tree, &len, | ||
773 | 703 | (NihTreeHandler)tree_handler2, &data2); | ||
774 | 704 | |||
775 | 705 | TEST_EQ (ret, 0); | ||
776 | 706 | TEST_EQ (len, NODE_COUNT); | ||
777 | 707 | TEST_EQ (data2, NODE_COUNT); | ||
778 | 708 | |||
779 | 709 | TEST_FEATURE ("with handler returning error"); | ||
780 | 710 | |||
781 | 711 | len = 0; | ||
782 | 712 | data2 = 0; | ||
783 | 713 | ret = nih_tree_foreach (tree, &len, | ||
784 | 714 | (NihTreeHandler)tree_handler3, &data2); | ||
785 | 715 | |||
786 | 716 | TEST_EQ (ret, -1); | ||
787 | 717 | TEST_EQ (len, ERROR_ON_NODE-1); | ||
788 | 718 | } | ||
789 | 719 | |||
790 | 720 | void | ||
791 | 721 | test_count (void) | ||
792 | 722 | { | ||
793 | 723 | NihTree *tree, *node1, *node2, *node3; | ||
794 | 724 | |||
795 | 725 | TEST_FUNCTION ("nih_tree_count"); | ||
796 | 726 | |||
797 | 727 | tree = nih_tree_new (NULL); | ||
798 | 728 | node1 = nih_tree_new (tree); | ||
799 | 729 | node2 = nih_tree_new (tree); | ||
800 | 730 | node3 = nih_tree_new (tree); | ||
801 | 731 | |||
802 | 732 | TEST_FEATURE ("with one initial entry"); | ||
803 | 733 | TEST_EQ (nih_tree_count (tree), 1); | ||
804 | 734 | |||
805 | 735 | TEST_FEATURE ("with increasing number of entries"); | ||
806 | 736 | |||
807 | 737 | nih_tree_add (tree, node1, NIH_TREE_LEFT); | ||
808 | 738 | TEST_EQ (nih_tree_count (tree), 2); | ||
809 | 739 | |||
810 | 740 | nih_tree_add (tree, node2, NIH_TREE_RIGHT); | ||
811 | 741 | TEST_EQ (nih_tree_count (tree), 3); | ||
812 | 742 | |||
813 | 743 | nih_tree_add (node1, node3, NIH_TREE_RIGHT); | ||
814 | 744 | TEST_EQ (nih_tree_count (tree), 4); | ||
815 | 745 | |||
816 | 746 | TEST_FEATURE ("with decreasing number of entries"); | ||
817 | 747 | nih_tree_remove (node3); | ||
818 | 748 | TEST_EQ (nih_tree_count (tree), 3); | ||
819 | 749 | |||
820 | 750 | nih_tree_remove (node2); | ||
821 | 751 | TEST_EQ (nih_tree_count (tree), 2); | ||
822 | 752 | |||
823 | 753 | nih_tree_remove (node1); | ||
824 | 754 | |||
825 | 755 | TEST_FEATURE ("with one final entry"); | ||
826 | 756 | TEST_EQ (nih_tree_count (tree), 1); | ||
827 | 757 | } | ||
828 | 758 | |||
829 | 592 | void | 759 | void |
830 | 593 | test_prev (void) | 760 | test_prev (void) |
831 | 594 | { | 761 | { |
832 | @@ -2214,6 +2381,8 @@ | |||
833 | 2214 | test_destroy (); | 2381 | test_destroy (); |
834 | 2215 | test_next (); | 2382 | test_next (); |
835 | 2216 | test_foreach (); | 2383 | test_foreach (); |
836 | 2384 | test_foreach_func (); | ||
837 | 2385 | test_count (); | ||
838 | 2217 | test_prev (); | 2386 | test_prev (); |
839 | 2218 | test_next_pre (); | 2387 | test_next_pre (); |
840 | 2219 | test_foreach_pre (); | 2388 | test_foreach_pre (); |
841 | 2220 | 2389 | ||
842 | === modified file 'nih/tree.c' | |||
843 | --- nih/tree.c 2009-06-23 09:29:37 +0000 | |||
844 | +++ nih/tree.c 2012-12-17 09:27:29 +0000 | |||
845 | @@ -619,3 +619,65 @@ | |||
846 | 619 | prev = tmp; | 619 | prev = tmp; |
847 | 620 | } | 620 | } |
848 | 621 | } | 621 | } |
849 | 622 | |||
850 | 623 | /** | ||
851 | 624 | * nih_tree_foreach: | ||
852 | 625 | * | ||
853 | 626 | * @tree: tree, | ||
854 | 627 | * @len: optional output parameter that will contain count of tree nodes, | ||
855 | 628 | * @handler: optional function called for each tree node, | ||
856 | 629 | * @data: optional data to pass to handler along with tree node. | ||
857 | 630 | * | ||
858 | 631 | * Iterate over specified tree. | ||
859 | 632 | * | ||
860 | 633 | * One of @len or @handler may be NULL. | ||
861 | 634 | * If @handler is NULL and @len is non-NULL, count of tree nodes will | ||
862 | 635 | * still be returned in @len. | ||
863 | 636 | * If @handler returns 1, @len will be set to the number of tree nodes | ||
864 | 637 | * processed successfully up to that point. | ||
865 | 638 | * | ||
866 | 639 | * Returns 0 on success (and when both @len and @handler are NULL), | ||
867 | 640 | * or -1 if handler returns an error. | ||
868 | 641 | **/ | ||
869 | 642 | int | ||
870 | 643 | nih_tree_foreach (NihTree *tree, size_t *len, | ||
871 | 644 | NihTreeHandler handler, void *data) | ||
872 | 645 | { | ||
873 | 646 | int ret; | ||
874 | 647 | |||
875 | 648 | nih_assert (tree); | ||
876 | 649 | |||
877 | 650 | if (len) *len = 0; | ||
878 | 651 | |||
879 | 652 | if (!len && !handler) return 0; | ||
880 | 653 | |||
881 | 654 | NIH_TREE_FOREACH_FULL (tree, iter, NULL, data) { | ||
882 | 655 | if (handler) { | ||
883 | 656 | ret = handler (iter, data); | ||
884 | 657 | if (!ret) return -1; | ||
885 | 658 | } | ||
886 | 659 | if (len) ++*len; | ||
887 | 660 | } | ||
888 | 661 | |||
889 | 662 | return 0; | ||
890 | 663 | } | ||
891 | 664 | |||
892 | 665 | /** | ||
893 | 666 | * nih_tree_count: | ||
894 | 667 | * | ||
895 | 668 | * @tree: tree. | ||
896 | 669 | * | ||
897 | 670 | * Returns count of number of entries in @tree. | ||
898 | 671 | **/ | ||
899 | 672 | size_t | ||
900 | 673 | nih_tree_count (NihTree *tree) | ||
901 | 674 | { | ||
902 | 675 | size_t len = 0; | ||
903 | 676 | int ret; | ||
904 | 677 | |||
905 | 678 | nih_assert (tree); | ||
906 | 679 | |||
907 | 680 | ret = nih_tree_foreach (tree, &len, NULL, NULL); | ||
908 | 681 | |||
909 | 682 | return (ret == -1 ? 0 : len); | ||
910 | 683 | } | ||
911 | 622 | 684 | ||
912 | === modified file 'nih/tree.h' | |||
913 | --- nih/tree.h 2009-06-23 09:29:37 +0000 | |||
914 | +++ nih/tree.h 2012-12-17 09:27:29 +0000 | |||
915 | @@ -138,6 +138,17 @@ | |||
916 | 138 | **/ | 138 | **/ |
917 | 139 | typedef int (*NihTreeFilter) (void *data, NihTree *node); | 139 | typedef int (*NihTreeFilter) (void *data, NihTree *node); |
918 | 140 | 140 | ||
919 | 141 | /** | ||
920 | 142 | * NihTreeHandler: | ||
921 | 143 | * @node: tree entry being visited, | ||
922 | 144 | * @data: data pointer. | ||
923 | 145 | * | ||
924 | 146 | * A tree handler is a function called for each tree node | ||
925 | 147 | * when iterating over a tree. | ||
926 | 148 | * | ||
927 | 149 | * Returns: TRUE if tree entry process correctly, else FALSE. | ||
928 | 150 | **/ | ||
929 | 151 | typedef int (*NihTreeHandler) (NihTree *node, void *data); | ||
930 | 141 | 152 | ||
931 | 142 | /** | 153 | /** |
932 | 143 | * NIH_TREE_FOREACH_FULL: | 154 | * NIH_TREE_FOREACH_FULL: |
933 | @@ -370,6 +381,13 @@ | |||
934 | 370 | NihTree * nih_tree_prev_post_full (NihTree *tree, NihTree *node, | 381 | NihTree * nih_tree_prev_post_full (NihTree *tree, NihTree *node, |
935 | 371 | NihTreeFilter filter, void *data); | 382 | NihTreeFilter filter, void *data); |
936 | 372 | 383 | ||
937 | 384 | int nih_tree_foreach (NihTree *tree, size_t *len, | ||
938 | 385 | NihTreeHandler handler, void *data) | ||
939 | 386 | __attribute__((unused)); | ||
940 | 387 | |||
941 | 388 | size_t nih_tree_count (NihTree *tree) | ||
942 | 389 | __attribute__((warn_unused_result, unused)); | ||
943 | 390 | |||
944 | 373 | NIH_END_EXTERN | 391 | NIH_END_EXTERN |
945 | 374 | 392 | ||
946 | 375 | #endif /* NIH_TREE_H */ | 393 | #endif /* NIH_TREE_H */ |
947 | 376 | 394 | ||
948 | === modified file 'po/libnih.pot' | |||
949 | --- po/libnih.pot 2010-12-23 22:04:08 +0000 | |||
950 | +++ po/libnih.pot 2012-12-17 09:27:29 +0000 | |||
951 | @@ -6,9 +6,9 @@ | |||
952 | 6 | #, fuzzy | 6 | #, fuzzy |
953 | 7 | msgid "" | 7 | msgid "" |
954 | 8 | msgstr "" | 8 | msgstr "" |
956 | 9 | "Project-Id-Version: libnih 1.0.3\n" | 9 | "Project-Id-Version: libnih 1.0.4\n" |
957 | 10 | "Report-Msgid-Bugs-To: libnih-bugs@netsplit.com\n" | 10 | "Report-Msgid-Bugs-To: libnih-bugs@netsplit.com\n" |
959 | 11 | "POT-Creation-Date: 2010-12-23 21:53+0000\n" | 11 | "POT-Creation-Date: 2011-05-08 12:30+0100\n" |
960 | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" | 12 | "PO-Revision-Date: YEAR-MO-DA HO:MI+ZONE\n" |
961 | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" | 13 | "Last-Translator: FULL NAME <EMAIL@ADDRESS>\n" |
962 | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" | 14 | "Language-Team: LANGUAGE <LL@li.org>\n" |
merge conflict to be resolved here.