blob: ac935c8cd0f56106ceddc8afa1d940990d48132b [file] [log] [blame]
b.liue9582032025-04-17 19:18:16 +08001/******************************************************************************
2*(C) Copyright 2008 Marvell International Ltd.
3* All Rights Reserved
4******************************************************************************/
5/*****************************************************************************
6* Utility Library
7*
8* DESCRIPTION
9* Functions to support generic linked list operations.
10*
11* Each linked list may contain zero or more nodes. Nodes are
12* singly linked to each other. For each linked list a head
13* pointer, tail pointer and node count are maintained.
14*
15* A typical linked list might look like this:
16*
17* List Header
18* .------------.
19* | head_p |------------>NODE1
20* | tail_p |----. |
21* | node_count |=3 \ V
22* `------------' \ NODE2
23* \ |
24* \ V
25* `-->NODE3
26* |
27* V
28* NULL
29*
30* Linked-list node structures are linked together like this:
31*
32* .-----------. .-----------. .-----------.
33* | next_p|-->| next_p|-->| next_p|-->NULL
34* | data area | | data area | | data area |
35* `-----------' `-----------' `-----------'
36*
37* EXAMPLE USAGE
38*
39* typedef struct myNode_S *myNode_P;
40* typedef struct myNode_S {
41* myNode_P next_p;
42* int a;
43* char b;
44* } myNode_T;
45*
46* {
47* utlLinkedList_t list;
48* myNode_T node1;
49* myNode_T node2;
50* myNode_T node3;
51* myNode_P node_p;
52*
53* utlLinkedList_t list;
54*
55* utlInitLinkedList(&list);
56*
57* node1.next_p = NULL;
58* node1.a = 42;
59* node1.b = 'a';
60*
61* node2.next_p = NULL;
62* node2.a = 100;
63* node2.b = 'b';
64*
65* node3.next_p = NULL;
66* node3.a = 88;
67* node3.b = 'c';
68*
69* utlPutTailNode(&list, myNode_T, &node1);
70* utlPutHeadNode(&list, myNode_T, &node2);
71*
72* --- insert node3 immediately after node1 ---
73* utlPutNode(&list, myNode_T, &node1, &node3);
74*
75* --- fetch the node immediately following node1 ---
76* node_p = utlGetNode(&list, myNode_T, NULL, &node1);
77* <use "node_p" here>
78*
79* node_p = utlGetHeadNode(&list, myNode_T);
80* <use "node_p" here>
81*
82* node_p = utlGetTailNode(&list, myNode_T);
83* <use "node_p" here>
84*
85* if (utlIsListEmpty(&list))
86* (void) printf("Linked list is empty.\n");
87* else
88* (void) printf("Linked list is NOT empty.\n");
89* }
90*****************************************************************************/
91
92#include <stdio.h>
93
94#include "utlTypes.h"
95#include "utlError.h"
96#include "utlLinkedList.h"
97
98
99/*---------------------------------------------------------------------------*
100* FUNCTION
101* utlInitLinkedList(list_p)
102* INPUT
103* list_p == pointer to an uninitialized utlLinkedList_T
104* OUTPUT
105* *list_p == an initialized linked list header
106* RETURNS
107* nothing
108* DESCRIPTION
109* Initailizes the linked list header specified by `list_p'.
110*---------------------------------------------------------------------------*/
111void utlInitLinkedList(const utlLinkedList_P list_p)
112{
113 list_p->head_p = NULL;
114 list_p->tail_p = NULL;
115 list_p->node_count = 0;
116}
117
118/*---------------------------------------------------------------------------*
119* FUNCTION
120* utlDoQueryPrevNode(list_p, node_p)
121* INPUT
122* list_p == pointer to a filled utlLinkedList_T
123* node_p == pointer to a utlLinkedListNode_T currently in `list_p'
124* OUTPUT
125* none
126* RETURNS
127* A pointer to the node preceding `node_p' in `list_p'
128* DESCRIPTION
129* Fetches the node that precedes `node_p' in `list_p'.
130*---------------------------------------------------------------------------*/
131utlLinkedListNode_P utlDoQueryPrevNode(const utlLinkedList_P list_p,
132 const utlLinkedListNode_P node_p)
133{
134 utlLinkedListNode_P prev_p;
135 utlLinkedListNode_P this_p;
136
137 utlAssert(list_p != NULL);
138 utlAssert(node_p != NULL);
139
140 utlAssert(!utlIsListEmpty(*list_p));
141
142 /*--- `list_p' cannot be empty since the node count was non-zero ---*/
143 utlAssert(list_p->head_p != NULL);
144 utlAssert(list_p->tail_p != NULL);
145
146 prev_p = NULL;
147 for (this_p = list_p->head_p; this_p != NULL; )
148 {
149 if (this_p == node_p)
150 break;
151
152 prev_p = this_p;
153 this_p = this_p->next_p;
154 }
155 /*This means not found, should return NULL*/
156 if(this_p == NULL)
157 return NULL;
158
159 return prev_p;
160}
161
162/*---------------------------------------------------------------------------*
163* FUNCTION
164* utlDoGetHeadNode(list_p)
165* INPUT
166* list_p == pointer to a filled utlLinkedList_T
167* OUTPUT
168* none
169* RETURNS
170* A pointer to the node that was unlinked. If `list_p' is empty, NULL
171* is returned.
172* DESCRIPTION
173* Unlinks the first node from the linked list specified by `list_p'.
174*
175* Note: This routine is carefully crafted so that it can interrupt
176* utlGetHeadNode() (assuming it is executing in a signal handler) at
177* any point, and `list_p' will not be corrupted.
178*---------------------------------------------------------------------------*/
179utlLinkedListNode_P utlDoGetHeadNode(const utlLinkedList_P list_p)
180{
181 utlLinkedListNode_P node_p;
182
183 utlAssert(list_p != NULL);
184
185 if (utlIsListEmpty(*list_p))
186 return NULL;
187
188 /*--- `list_p' cannot be empty since the node count was non-zero ---*/
189 utlAssert(list_p->head_p != NULL);
190 utlAssert(list_p->tail_p != NULL);
191
192 /*--- grab first node... ---*/
193 node_p = list_p->head_p;
194 list_p->head_p = list_p->head_p->next_p;
195
196 /*--- `list_p' now empty? then fix tail pointer ---*/
197 if (list_p->head_p == NULL)
198 list_p->tail_p = NULL;
199
200 node_p->next_p = NULL;
201
202 list_p->node_count--;
203
204 return node_p;
205}
206
207/*---------------------------------------------------------------------------*
208* FUNCTION
209* utlDoGetNode(list_p, prev_p, node_p)
210* INPUT
211* list_p == pointer to a filled utlLinkedList_T
212* prev_p == pointer to the node preceding `node_p', or NULL
213* node_p == pointer to a utlLinkedListNode_T currently in `list_p'
214* OUTPUT
215* none
216* RETURNS
217* A pointer to the node that was unlinked. If the list was empty, NULL
218* is returned.
219* DESCRIPTION
220* Removes the node pointed to by `node_p' from the linked list specified
221* by `list_p'. `prev_p' must point to the node preceeding `node_p', or
222* be NULL. For maximum run-time performance, "prev_p" should be non-NULL,
223* unless `node_p' points to the first node in the list.
224*---------------------------------------------------------------------------*/
225utlLinkedListNode_P utlDoGetNode(const utlLinkedList_P list_p,
226 const utlLinkedListNode_P prev_p,
227 const utlLinkedListNode_P node_p)
228{
229 utlLinkedListNode_P nprev_p;
230
231 utlAssert(list_p != NULL);
232 utlAssert(node_p != NULL);
233
234 /*--- nothing to get? ---*/
235 if (utlIsListEmpty(*list_p))
236 return NULL;
237
238 /*--- is `node_p' the head node in `list_p'? ---*/
239 if (node_p == list_p->head_p)
240 return utlDoGetHeadNode(list_p);
241
242 /*--- `list_p' cannot be empty since the node count was non-zero ---*/
243 utlAssert(list_p->head_p != NULL);
244 utlAssert(list_p->tail_p != NULL);
245
246 /*--- if `prev_p' node was not specified, find it ---*/
247 if (prev_p == NULL) nprev_p = utlDoQueryPrevNode(list_p, node_p);
248 else nprev_p = prev_p;
249
250 /*--- since `node_p' was not the head node in `list_p', `nprev_p' must be
251 known, and must be the node preceeding `node_p'.
252 TODO: If not meet, it means something error happen, but since it's not fatal error,
253 maybe system can handle the NULL return error, so here return NULL
254 instead of assert here.*/
255 if(nprev_p == NULL)
256 return NULL;
257 utlAssert(nprev_p != NULL);
258 utlAssert(nprev_p->next_p == node_p);
259
260 /*--- unlink `node_p' from `list_p' ---*/
261 nprev_p->next_p = node_p->next_p;
262 node_p->next_p = NULL;
263
264 /*--- if `node_p' was the last node in `list_p', fix up tail pointer ---*/
265 if (node_p == list_p->tail_p)
266 list_p->tail_p = nprev_p;
267
268 list_p->node_count--;
269
270 return node_p;
271}
272
273/*---------------------------------------------------------------------------*
274* FUNCTION
275* utlDoGetTailNode(list_p)
276* INPUT
277* list_p == pointer to a filled utlLinkedList_T
278* OUTPUT
279* none
280* RETURNS
281* A pointer to the node that was unlinked. If `list_p' is empty,
282* NULL is returned.
283* DESCRIPTION
284* Unlinks the last node from the linked list specified by `list_p'.
285*---------------------------------------------------------------------------*/
286utlLinkedListNode_P utlDoGetTailNode(const utlLinkedList_P list_p)
287{
288 utlLinkedListNode_P prev_p;
289 utlLinkedListNode_P this_p;
290 utlLinkedListNode_P node_p;
291
292 utlAssert(list_p != NULL);
293
294 if (utlIsListEmpty(*list_p))
295 return NULL;
296
297 /*--- `list_p' cannot be empty since the node count was non-zero ---*/
298 utlAssert(list_p->head_p != NULL);
299 utlAssert(list_p->tail_p != NULL);
300
301 /*--- find node preceding current tail node ---*/
302 prev_p = NULL;
303 for (this_p = list_p->head_p; this_p != NULL; )
304 {
305 if (this_p == list_p->tail_p)
306 break;
307
308 prev_p = this_p;
309 this_p = this_p->next_p;
310 }
311
312 /*--- grab last node... ---*/
313 node_p = list_p->tail_p;
314 list_p->tail_p = prev_p;
315
316 /*--- fix up new `last node' ---*/
317 if (prev_p != NULL)
318 prev_p->next_p = NULL;
319
320 /*--- `list_p' now empty? then fix tail pointer ---*/
321 if (list_p->tail_p == NULL)
322 list_p->head_p = NULL;
323
324 node_p->next_p = NULL;
325
326 list_p->node_count--;
327
328 return node_p;
329}
330
331/*---------------------------------------------------------------------------*
332* FUNCTION
333* utlDoPutHeadNode(list_p, node_p)
334* INPUT
335* list_p == pointer to a filled utlLinkedList_T
336* node_p == pointer to a filled utlLinkedListNode_T
337* OUTPUT
338* none
339* RETURNS
340* nothing
341* DESCRIPTION
342* Attachs the node pointed to by `node_p' to the head of the linked list
343* specified by `list_p'.
344*---------------------------------------------------------------------------*/
345void utlDoPutHeadNode(const utlLinkedList_P list_p,
346 const utlLinkedListNode_P node_p)
347{
348 utlAssert(list_p != NULL);
349 utlAssert(node_p != NULL);
350
351 node_p->next_p = list_p->head_p;
352
353 /*--- `list_p' empty? then fix tail pointer ---*/
354 if (utlIsListEmpty(*list_p))
355 list_p->tail_p = node_p;
356
357 /*--- attach `node_p' to `list_p' ---*/
358 list_p->head_p = node_p;
359
360 list_p->node_count++;
361}
362
363/*---------------------------------------------------------------------------*
364* FUNCTION
365* utlDoPutNode(list_p, here_p, node_p)
366* INPUT
367* list_p == pointer to a filled utlLinkedList_T
368* here_p == pointer to a node in the above list
369* node_p == pointer to a filled utlLinkedListNode_T
370* OUTPUT
371* none
372* RETURNS
373* nothing
374* DESCRIPTION
375* Inserts the node pointed to by `node_p' after the node pointed to by
376* `ptr_p' in the list specified by `list_p'. If `ptr_p' equals NULL
377* then the node is linked to the head of `list_p'.
378*---------------------------------------------------------------------------*/
379void utlDoPutNode(const utlLinkedList_P list_p,
380 const utlLinkedListNode_P here_p,
381 const utlLinkedListNode_P node_p)
382{
383 utlAssert(list_p != NULL);
384 utlAssert(node_p != NULL);
385
386 /*--- link `node_p' to head of list? ---*/
387 if (here_p == NULL)
388 {
389 utlDoPutHeadNode(list_p, node_p);
390 return;
391 }
392
393 /*--- `list_p' cannot be empty since `here_p' is non-NULL ---*/
394 utlAssert(list_p->head_p != NULL);
395 utlAssert(list_p->tail_p != NULL);
396 utlAssert(!utlIsListEmpty(*list_p));
397
398 /*--- insert `node_p' after `here_p'... ---*/
399 node_p->next_p = here_p->next_p;
400 here_p->next_p = node_p;
401
402 /*--- is `node_p' the new tail node? ---*/
403 if (here_p == list_p->tail_p)
404 list_p->tail_p = node_p;
405
406 list_p->node_count++;
407}
408
409/*---------------------------------------------------------------------------*
410* FUNCTION
411* utlDoPutTailNode(list_p, node_p)
412* INPUT
413* list_p == pointer to a filled utlLinkedList_T
414* node_p == pointer to a filled utlLinkedListNode_T
415* OUTPUT
416* none
417* RETURNS
418* nothing
419* DESCRIPTION
420* Attachs the node pointed to by `node_p' to the tail of the linked list
421* specified by `list_p'.
422*
423* Note: This routine is carefully crafted so that it can be interrupted
424* at any point and `list_p' processed by utlGetHeadNode() (which would
425* be executed via a signal handler) without corruption.
426*---------------------------------------------------------------------------*/
427void utlDoPutTailNode(const utlLinkedList_P list_p,
428 const utlLinkedListNode_P node_p)
429{
430 utlAssert(list_p != NULL);
431 utlAssert(node_p != NULL);
432
433 node_p->next_p = NULL;
434
435 /*--- `list_p' empty? then fix head pointer ---*/
436 if (utlIsListEmpty(*list_p))
437 {
438 list_p->tail_p = node_p;
439 list_p->head_p = node_p;
440 }
441 else
442 {
443 list_p->tail_p->next_p = node_p;
444 list_p->tail_p = node_p;
445 }
446
447 list_p->node_count++;
448}
449
450/*---------------------------------------------------------------------------*
451* FUNCTION
452* utlPutHeadList(list1_p, list2_p)
453* INPUT
454* list1_p == pointer to a utlLinkedList_T
455* list2_p == pointer to a utlLinkedList_T
456* OUTPUT
457* *list1_p == a full linked list header
458* *list2_p == an empy linked list header
459* RETURNS
460* nothing
461* DESCRIPTION
462* Merges two lists by moving all the nodes in `list2_p' onto the head
463* of `list1_p'.
464*---------------------------------------------------------------------------*/
465void utlPutHeadList(const utlLinkedList_P list1_p,
466 const utlLinkedList_P list2_p)
467{
468 utlAssert(list1_p != NULL);
469 utlAssert(list2_p != NULL);
470
471 /*--- is `list2_p' empty? ---*/
472 if (utlIsListEmpty(*list2_p))
473 return;
474
475 list2_p->tail_p->next_p = list1_p->head_p;
476
477 /*--- `list1_p' empty? then fix tail pointer ---*/
478 if (utlIsListEmpty(*list1_p))
479 list1_p->tail_p = list2_p->tail_p;
480
481 /*--- attach `node_p' to `list_p' ---*/
482 list1_p->head_p = list2_p->head_p;
483
484 list1_p->node_count += list2_p->node_count;
485
486 utlInitLinkedList(list2_p);
487}
488
489/*---------------------------------------------------------------------------*
490* FUNCTION
491* utlPutTailList(list1_p, list2_p)
492* INPUT
493* list1_p == pointer to a utlLinkedList_T
494* list2_p == pointer to a utlLinkedList_T
495* OUTPUT
496* *list1_p == a full linked list header
497* *list2_p == an empy linked list header
498* RETURNS
499* nothing
500* DESCRIPTION
501* Merges two lists by moving all the nodes in `list2_p' onto the tail
502* of `list1_p'.
503*---------------------------------------------------------------------------*/
504void utlPutTailList(const utlLinkedList_P list1_p,
505 const utlLinkedList_P list2_p)
506{
507 utlAssert(list1_p != NULL);
508 utlAssert(list2_p != NULL);
509
510 /*--- is `list2_p' empty? ---*/
511 if (utlIsListEmpty(*list2_p))
512 return;
513
514 /*--- is `list1_p' empty? then fix head pointer ---*/
515 if (utlIsListEmpty(*list1_p)) list1_p->head_p = list2_p->head_p;
516 else list1_p->tail_p->next_p = list2_p->head_p;
517
518 /*--- attach `list2_p' to tail of `list1_p' ---*/
519 list1_p->tail_p = list2_p->tail_p;
520
521 list1_p->node_count += list2_p->node_count;
522
523 utlInitLinkedList(list2_p);
524}
525
526#ifdef utlTEST
527/*---------------------------------------------------------------------------*
528* FUNCTION
529* linkedListTest()
530* INPUT
531* none
532* OUTPUT
533* none
534* RETURNS
535* "true" for pass, "false" for failure
536*---------------------------------------------------------------------------*/
537bool linkedListTest(void)
538{
539 utlLinkedList_T list;
540 utlLinkedListNode_T node[10];
541 utlLinkedListNode_P this_p;
542 utlLinkedListNode_P prev_p;
543
544 /*--- Check `utlGetHeadNode()' ------------------------------------------*/
545 node[0].next_p = &(node[1]);
546 node[1].next_p = &(node[2]);
547 node[2].next_p = NULL;
548
549 list.head_p = &(node[0]);
550 list.tail_p = &(node[2]);
551 list.node_count = 3;
552
553 if (utlGetHeadNode(&list, utlLinkedListNode_T) != &(node[0]))
554 {
555 (void)fprintf(stderr, "linkedListTest: utlGetHeadNode(1) failed\n");
556 return false;
557 }
558 if (utlGetHeadNode(&list, utlLinkedListNode_T) != &(node[1]))
559 {
560 (void)fprintf(stderr, "linkedListTest: utlGetHeadNode(2) failed\n");
561 return false;
562 }
563 if (utlGetHeadNode(&list, utlLinkedListNode_T) != &(node[2]))
564 {
565 (void)fprintf(stderr, "linkedListTest: utlGetHeadNode(3) failed\n");
566 return false;
567 }
568 if (utlGetHeadNode(&list, utlLinkedListNode_T) != NULL)
569 {
570 (void)fprintf(stderr, "linkedListTest: utlGetHeadNode(4) failed\n");
571 return false;
572 }
573 if ((list.head_p != NULL) ||
574 (list.tail_p != NULL) ||
575 (list.node_count != 0))
576 {
577 (void)fprintf(stderr, "linkedListTest: utlGetHeadNode(5) failed\n");
578 return false;
579 }
580
581
582 /*--- Check `utlGetNode()' ----------------------------------------------*/
583 node[0].next_p = &(node[1]);
584 node[1].next_p = &(node[2]);
585 node[2].next_p = &(node[3]);
586 node[3].next_p = &(node[4]);
587 node[4].next_p = NULL;
588
589 list.head_p = &(node[0]);
590 list.tail_p = &(node[4]);
591 list.node_count = 5;
592
593 prev_p = NULL;
594 this_p = &(node[0]);
595 if (utlGetNode(&list, utlLinkedListNode_T, prev_p, this_p) != &(node[0]))
596 {
597 (void)fprintf(stderr, "linkedListTest: utlGetNode(1) failed\n");
598 return false;
599 }
600 prev_p = &(node[1]);
601 this_p = &(node[2]);
602 if (utlGetNode(&list, utlLinkedListNode_T, prev_p, this_p) != &(node[2]))
603 {
604 (void)fprintf(stderr, "linkedListTest: utlGetNode(2) failed\n");
605 return false;
606 }
607 prev_p = &(node[3]);
608 this_p = &(node[4]);
609 if (utlGetNode(&list, utlLinkedListNode_T, prev_p, this_p) != &(node[4]))
610 {
611 (void)fprintf(stderr, "linkedListTest: utlGetNode(3) failed\n");
612 return false;
613 }
614 if ((list.head_p != &(node[1])) ||
615 (list.tail_p != &(node[3])) ||
616 (list.node_count != 2))
617 {
618 (void)fprintf(stderr, "linkedListTest: utlGetNode(4) failed\n");
619 return false;
620 }
621
622 node[0].next_p = &(node[1]);
623 node[1].next_p = &(node[2]);
624 node[2].next_p = &(node[3]);
625 node[3].next_p = &(node[4]);
626 node[4].next_p = NULL;
627
628 list.head_p = &(node[0]);
629 list.tail_p = &(node[4]);
630 list.node_count = 5;
631
632 prev_p = NULL;
633 this_p = &(node[0]);
634 if (utlGetNode(&list, utlLinkedListNode_T, prev_p, this_p) != &(node[0]))
635 {
636 (void)fprintf(stderr, "linkedListTest: utlGetNode(5) failed\n");
637 return false;
638 }
639 prev_p = NULL;
640 this_p = &(node[2]);
641 if (utlGetNode(&list, utlLinkedListNode_T, prev_p, this_p) != &(node[2]))
642 {
643 (void)fprintf(stderr, "linkedListTest: utlGetNode(6) failed\n");
644 return false;
645 }
646 prev_p = NULL;
647 this_p = &(node[4]);
648 if (utlGetNode(&list, utlLinkedListNode_T, prev_p, this_p) != &(node[4]))
649 {
650 (void)fprintf(stderr, "linkedListTest: utlGetNode(7) failed\n");
651 return false;
652 }
653 if ((list.head_p != &(node[1])) ||
654 (list.tail_p != &(node[3])) ||
655 (list.node_count != 2))
656 {
657 (void)fprintf(stderr, "linkedListTest: utlGetNode(8) failed\n");
658 return false;
659 }
660
661
662 /*--- Check `utlInitLinkedList()' ---------------------------------------*/
663 utlInitLinkedList(&list);
664 if ((list.head_p != NULL) ||
665 (list.tail_p != NULL) ||
666 (list.node_count != 0))
667 {
668 (void)fprintf(stderr, "linkedListTest: utlInitLinkedList(1) failed\n");
669 return false;
670 }
671
672
673 /*--- Check `utlGetTailNode()' ------------------------------------------*/
674 node[0].next_p = &(node[1]);
675 node[1].next_p = &(node[2]);
676 node[2].next_p = NULL;
677
678 list.head_p = &(node[0]);
679 list.tail_p = &(node[2]);
680 list.node_count = 3;
681
682 if (utlGetTailNode(&list, utlLinkedListNode_T) != &(node[2]))
683 {
684 (void)fprintf(stderr, "linkedListTest: utlGetTailNode(1) failed\n");
685 return false;
686 }
687 if (utlGetTailNode(&list, utlLinkedListNode_T) != &(node[1]))
688 {
689 (void)fprintf(stderr, "linkedListTest: utlGetTailNode(2) failed\n");
690 return false;
691 }
692 if (utlGetTailNode(&list, utlLinkedListNode_T) != &(node[0]))
693 {
694 (void)fprintf(stderr, "linkedListTest: utlGetTailNode(3) failed\n");
695 return false;
696 }
697 if (utlGetTailNode(&list, utlLinkedListNode_T) != NULL)
698 {
699 (void)fprintf(stderr, "linkedListTest: utlGetTailNode(4) failed\n");
700 return false;
701 }
702 if ((list.head_p != NULL) ||
703 (list.tail_p != NULL) ||
704 (list.node_count != 0))
705 {
706 (void)fprintf(stderr, "linkedListTest: utlGetTailNode(5) failed\n");
707 return false;
708 }
709
710
711 /*--- Check `utlPutHeadNode()' ------------------------------------------*/
712 utlInitLinkedList(&list);
713
714 utlPutHeadNode(&list, utlLinkedListNode_T, &(node[4]));
715 utlPutHeadNode(&list, utlLinkedListNode_T, &(node[3]));
716 utlPutHeadNode(&list, utlLinkedListNode_T, &(node[2]));
717 utlPutHeadNode(&list, utlLinkedListNode_T, &(node[1]));
718 utlPutHeadNode(&list, utlLinkedListNode_T, &(node[0]));
719 if ((list.head_p != &(node[0])) ||
720 (list.tail_p != &(node[4])) ||
721 (list.node_count != 5))
722 {
723 (void)fprintf(stderr, "linkedListTest: utlPutHeadNode(1) failed\n");
724 return false;
725 }
726
727
728 /*--- Check `utlPutNode()' ----------------------------------------------*/
729 utlInitLinkedList(&list);
730
731 utlPutNode(&list, utlLinkedListNode_T, NULL, &(node[2]));
732 utlPutNode(&list, utlLinkedListNode_T, NULL, &(node[1]));
733 utlPutNode(&list, utlLinkedListNode_T, &(node[2]), &(node[3]));
734 utlPutNode(&list, utlLinkedListNode_T, NULL, &(node[0]));
735 utlPutNode(&list, utlLinkedListNode_T, &(node[3]), &(node[4]));
736 if ((list.head_p != &(node[0])) ||
737 (list.tail_p != &(node[4])) ||
738 (list.node_count != 5))
739 {
740 (void)fprintf(stderr, "linkedListTest: utlPutNode(1) failed\n");
741 return false;
742 }
743
744
745 /*--- Check `utlPutTailNode()' ------------------------------------------*/
746 utlInitLinkedList(&list);
747
748 utlPutTailNode(&list, utlLinkedListNode_T, &(node[0]));
749 utlPutTailNode(&list, utlLinkedListNode_T, &(node[1]));
750 utlPutTailNode(&list, utlLinkedListNode_T, &(node[2]));
751 utlPutTailNode(&list, utlLinkedListNode_T, &(node[3]));
752 utlPutTailNode(&list, utlLinkedListNode_T, &(node[4]));
753 if ((list.head_p != &(node[0])) ||
754 (list.tail_p != &(node[4])) ||
755 (list.node_count != 5))
756 {
757 (void)fprintf(stderr, "linkedListTest: utlPutTailNode(1) failed\n");
758 return false;
759 }
760
761
762 /*--- Check `utlQueryPrevNode()' ----------------------------------------*/
763 node[0].next_p = &(node[1]);
764 node[1].next_p = &(node[2]);
765 node[2].next_p = NULL;
766
767 list.head_p = &(node[0]);
768 list.tail_p = &(node[2]);
769 list.node_count = 3;
770
771 if (utlQueryPrevNode(&list, utlLinkedListNode_T, &(node[0])) != NULL)
772 {
773 (void)fprintf(stderr, "linkedListTest: utlQueryPrevNode(1) failed\n");
774 return false;
775 }
776 if (utlQueryPrevNode(&list, utlLinkedListNode_T, &(node[1])) != &(node[0]))
777 {
778 (void)fprintf(stderr, "linkedListTest: utlQueryPrevNode(2) failed\n");
779 return false;
780 }
781 if (utlQueryPrevNode(&list, utlLinkedListNode_T, &(node[2])) != &(node[1]))
782 {
783 (void)fprintf(stderr, "linkedListTest: utlQueryPrevNode(3) failed\n");
784 return false;
785 }
786
787 return true;
788}
789#endif /* utlTEST */
790