1 /*----------------------------------------------------------------------------
2 --
3 --  Module:           LstLinked
4 --
5 --  Project:          Tools - General C objects.
6 --  System:           Lst - Linked lists.
7 --    Subsystem:      <>
8 --    Function block: <>
9 --
10 --  Description:
11 --    Manages a double linked list. Operations for create, insert,
12 --    delete etc.
13 --
14 --  Filename:         LstLinked.c
15 --
16 --  Authors:          Roger Larsson, Ulrika Bornetun
17 --  Creation date:    1990-12-01
18 --
19 --
20 --  (C) Copyright Ulrika Bornetun, Roger Larsson (1995)
21 --      All rights reserved
22 --
23 --  Permission to use, copy, modify, and distribute this software and its
24 --  documentation for any purpose and without fee is hereby granted,
25 --  provided that the above copyright notice appear in all copies. Ulrika
26 --  Bornetun and Roger Larsson make no representations about the usability
27 --  of this software for any purpose. It is provided "as is" without express
28 --  or implied warranty.
29 ----------------------------------------------------------------------------*/
30 
31 /* SCCS module identifier. */
32 static char SCCSID[] = "@(#) Module: LstLinked.c, Version: 1.1, Date: 95/02/18 14:32:28";
33 
34 
35 /*----------------------------------------------------------------------------
36 --  Include files
37 ----------------------------------------------------------------------------*/
38 
39 #include <stdlib.h>
40 #include <memory.h>
41 #include <stdio.h>
42 
43 #include "System.h"
44 #include "LstLinked.h"
45 
46 
47 /*----------------------------------------------------------------------------
48 --  Macro definitions
49 ----------------------------------------------------------------------------*/
50 
51 
52 /*----------------------------------------------------------------------------
53 --  Type declarations
54 ----------------------------------------------------------------------------*/
55 
56 
57 /*----------------------------------------------------------------------------
58 --  Global definitions
59 ----------------------------------------------------------------------------*/
60 
61 
62 /*----------------------------------------------------------------------------
63 --  Function prototypes
64 ----------------------------------------------------------------------------*/
65 
66 
67 
68 /*----------------------------------------------------------------------------
69 --  Functions
70 ----------------------------------------------------------------------------*/
71 
72 LST_DESC_TYPE
LstLinkNew(int record_size,EQUALS_FUNC_TYPE equals_func)73   LstLinkNew( int               record_size,
74               EQUALS_FUNC_TYPE  equals_func )
75 {
76 
77   /* Variables. */
78   LST_DESC_TYPE  list_desc;
79 
80 
81   /* Code. */
82 
83   list_desc = SysNew( LST_DESC_RECORD );
84 
85   list_desc -> head    = NULL;
86   list_desc -> tail    = NULL;
87   list_desc -> current = NULL;
88 
89   list_desc -> elements    = 0;
90   list_desc -> record_size = record_size;
91   list_desc -> equals_func = equals_func;
92 
93 
94   return( list_desc );
95 
96 } /* LstLinkNew */
97 
98 
99 /*----------------------------------------------------------------------*/
100 
101 void
LstLinkClear(LST_DESC_TYPE list_desc)102   LstLinkClear( LST_DESC_TYPE  list_desc )
103 {
104 
105   /* Variables. */
106   LST_RECORD_TYPE  *node_ref;
107   LST_RECORD_TYPE  *tmp_ref;
108 
109 
110   /* Code. */
111 
112   if( list_desc == NULL )
113     return;
114 
115   node_ref = list_desc -> head;
116 
117   while( node_ref != NULL ) {
118 
119     tmp_ref  = node_ref;
120     node_ref = node_ref -> next;
121 
122     SysFree( tmp_ref -> record );
123     SysFree( tmp_ref );
124 
125   } /* while */
126 
127   list_desc -> head    = NULL;
128   list_desc -> tail    = NULL;
129   list_desc -> current = NULL;
130 
131   list_desc -> elements = 0;
132 
133 
134   return;
135 
136 } /* LstLinkClear */
137 
138 
139 /*----------------------------------------------------------------------*/
140 
141 void
LstLinkClearDataAndList(LST_DESC_TYPE list_desc,CLEAR_DATA_FUNC_TYPE clear_func)142   LstLinkClearDataAndList( LST_DESC_TYPE         list_desc,
143                            CLEAR_DATA_FUNC_TYPE  clear_func )
144 {
145 
146   /* Variables. */
147   LST_RECORD_TYPE  *node_ref;
148   LST_RECORD_TYPE  *tmp_ref;
149 
150 
151   /* Code. */
152 
153   if( list_desc == NULL )
154     return;
155 
156   node_ref = list_desc -> head;
157 
158   while( node_ref != NULL ) {
159 
160     tmp_ref  = node_ref;
161     node_ref = node_ref -> next;
162 
163     /* Call function to clear allocated data. */
164     ( *clear_func )( (void *)tmp_ref -> record );
165 
166     SysFree( tmp_ref -> record );
167     SysFree( tmp_ref );
168 
169   } /* while */
170 
171   list_desc -> head    = NULL;
172   list_desc -> tail    = NULL;
173   list_desc -> current = NULL;
174 
175   list_desc -> elements = 0;
176 
177 
178   return;
179 
180 } /* LstLinkClearDataAndList */
181 
182 
183 /*----------------------------------------------------------------------*/
184 
185 LST_STATUS
LstLinkInsertFirst(LST_DESC_TYPE list_desc,void * record)186   LstLinkInsertFirst( LST_DESC_TYPE  list_desc,
187                       void           *record )
188 {
189 
190   /* Variables. */
191   char             *new_record;
192   LST_RECORD_TYPE  *new_node;
193 
194 
195   /* Code. */
196 
197   if( list_desc == NULL )
198     return( LST_ERROR );
199 
200   /* Create the new node and copy the record. */
201   new_record = SysMalloc( list_desc -> record_size );
202   memcpy( new_record, record, list_desc -> record_size );
203 
204   new_node = SysNew( LST_RECORD_TYPE );
205   new_node -> record = new_record;
206 
207   /* Link the new record into the list. */
208   if( list_desc -> head == NULL ) {
209 
210     new_node -> next     = NULL;
211     new_node -> previous = NULL;
212 
213     list_desc -> head    = new_node;
214     list_desc -> tail    = new_node;
215     list_desc -> current = new_node;
216 
217   } else {
218 
219     new_node -> next     = list_desc -> head;
220     new_node -> previous = NULL;
221 
222     list_desc -> head -> previous = new_node;
223     list_desc -> head             = new_node;
224 
225   } /* if */
226 
227   list_desc -> elements++;
228 
229 
230   return( LST_OK );
231 
232 } /* LstLinkInsertFirst */
233 
234 
235 /*----------------------------------------------------------------------*/
236 
237 LST_STATUS
LstLinkInsertLast(LST_DESC_TYPE list_desc,void * record)238   LstLinkInsertLast( LST_DESC_TYPE  list_desc,
239                      void           *record )
240 {
241 
242   /* Variables. */
243   char             *new_record;
244   LST_RECORD_TYPE  *new_node;
245 
246 
247   /* Code. */
248 
249   if( list_desc == NULL )
250     return( LST_ERROR );
251 
252   /* Create the new node and copy the record. */
253   new_record = SysMalloc( list_desc -> record_size );
254   memcpy( new_record, record, list_desc -> record_size );
255 
256   new_node = SysNew( LST_RECORD_TYPE );
257   new_node -> record = new_record;
258 
259   /* Link the new record into the list. */
260   if( list_desc -> head == NULL ) {
261 
262     new_node -> next     = NULL;
263     new_node -> previous = NULL;
264 
265     list_desc -> head    = new_node;
266     list_desc -> tail    = new_node;
267     list_desc -> current = new_node;
268 
269   } else {
270 
271     list_desc -> tail -> next = new_node;
272 
273     new_node -> next     = NULL;
274     new_node -> previous = list_desc -> tail;
275 
276     list_desc -> tail = new_node;
277 
278   } /* if */
279 
280   list_desc -> elements++;
281 
282 
283   return( LST_OK );
284 
285 } /* LstLinkInsertLast */
286 
287 
288 /*----------------------------------------------------------------------*/
289 
290 LST_STATUS
LstLinkInsertCurrent(LST_DESC_TYPE list_desc,void * record)291   LstLinkInsertCurrent( LST_DESC_TYPE  list_desc,
292                         void           *record )
293 {
294 
295   /* Variables. */
296   char             *new_record;
297   LST_RECORD_TYPE  *new_node;
298 
299 
300   /* Code. */
301 
302   if( list_desc == NULL )
303     return( LST_ERROR );
304 
305   /* If the current pointer is not defined, insert at the beginning. */
306   if( (list_desc -> current == NULL) || (list_desc -> head == NULL) )
307     return( LstLinkInsertLast( list_desc, record ) );
308 
309   /* Create the new node and copy the record. */
310   new_record = SysMalloc( list_desc -> record_size );
311   memcpy( new_record, record, list_desc -> record_size );
312 
313   new_node = SysNew( LST_RECORD_TYPE );
314   new_node -> record = new_record;
315 
316   /* Link the new record into the list. */
317   if( list_desc -> current -> previous == NULL ) {
318 
319     new_node -> next     = list_desc -> current;
320     new_node -> previous = NULL;
321 
322     list_desc -> current -> previous = new_node;
323     list_desc -> head                = new_node;
324     list_desc -> current             = new_node;
325 
326   } else {
327 
328     new_node -> next     = list_desc -> current;
329     new_node -> previous = list_desc -> current -> previous;
330 
331     list_desc -> current -> previous -> next = new_node;
332     list_desc -> current -> previous         = new_node;
333 
334     list_desc -> current = new_node;
335 
336   } /* if */
337 
338   list_desc -> elements++;
339 
340 
341   return( LST_OK );
342 
343 } /* LstLinkInsertCurrent */
344 
345 
346 /*----------------------------------------------------------------------*/
347 
348 LST_STATUS
LstLinkCurrentFirst(LST_DESC_TYPE list_desc)349   LstLinkCurrentFirst( LST_DESC_TYPE  list_desc )
350 {
351 
352   /* Code. */
353 
354   if( list_desc == NULL )
355     return( LST_ERROR );
356 
357   list_desc -> current = NULL;
358 
359   if( list_desc -> head == NULL )
360     return( LST_STUCK );
361 
362   list_desc -> current = list_desc -> head;
363 
364 
365   return( LST_OK );
366 
367 } /* LstLinkCurrentFirst */
368 
369 
370 /*----------------------------------------------------------------------*/
371 
372 LST_STATUS
LstLinkCurrentLast(LST_DESC_TYPE list_desc)373   LstLinkCurrentLast( LST_DESC_TYPE  list_desc )
374 {
375 
376   /* Code. */
377 
378   if( list_desc == NULL )
379     return( LST_ERROR );
380 
381   list_desc -> current = NULL;
382 
383   if( list_desc -> tail == NULL )
384     return( LST_STUCK );
385 
386   list_desc -> current = list_desc -> tail;
387 
388 
389   return( LST_OK );
390 
391 } /* LstLinkCurrentLast */
392 
393 
394 /*----------------------------------------------------------------------*/
395 
396 LST_STATUS
LstLinkCurrentPosition(LST_DESC_TYPE list_desc,int position)397   LstLinkCurrentPosition( LST_DESC_TYPE  list_desc,
398                           int            position )
399 {
400 
401   /* Variables. */
402   int               counter = 1;
403   LST_RECORD_TYPE   *ref;
404 
405 
406   /* Code. */
407 
408   if( list_desc == NULL )
409     return( LST_ERROR );
410 
411   list_desc -> current = NULL;
412 
413   if( list_desc -> head == NULL )
414     return( LST_STUCK );
415 
416   ref = list_desc -> head;
417 
418   /* Try to move to the position. */
419   while( ref != NULL && counter < position ) {
420     ref = ref -> next;
421     counter++;
422   }
423 
424   /* Did we reach the end? */
425   if( ref == NULL )
426     return( LST_STUCK );
427 
428   list_desc -> current = ref;
429 
430 
431   return( LST_OK );
432 
433 } /* LstLinkCurrentPosition */
434 
435 
436 /*----------------------------------------------------------------------*/
437 
438 LST_STATUS
LstLinkCurrentNext(LST_DESC_TYPE list_desc)439   LstLinkCurrentNext( LST_DESC_TYPE  list_desc )
440 {
441 
442   /* Code. */
443 
444   if( list_desc == NULL )
445     return( LST_ERROR );
446 
447   if( list_desc -> current == NULL )
448     return( LST_STUCK );
449 
450   if( list_desc -> current -> next == NULL )
451     return( LST_STUCK );
452 
453   list_desc -> current = list_desc -> current -> next;
454 
455 
456   return( LST_OK );
457 
458 } /* LstLinkCurrentNext */
459 
460 
461 /*----------------------------------------------------------------------*/
462 
463 LST_STATUS
LstLinkCurrentPrevious(LST_DESC_TYPE list_desc)464   LstLinkCurrentPrevious( LST_DESC_TYPE  list_desc )
465 {
466 
467   /* Code. */
468 
469   if( list_desc == NULL )
470     return( LST_ERROR );
471 
472   if( list_desc -> current == NULL )
473     return( LST_STUCK );
474 
475   if( list_desc -> current -> previous == NULL )
476     return( LST_STUCK );
477 
478   list_desc -> current = list_desc -> current -> previous;
479 
480 
481   return( LST_OK );
482 
483 } /* LstLinkCurrentPrevious */
484 
485 
486 /*----------------------------------------------------------------------*/
487 
488 LST_STATUS
LstLinkDeleteFirst(LST_DESC_TYPE list_desc)489   LstLinkDeleteFirst( LST_DESC_TYPE  list_desc )
490 {
491 
492   /* Code. */
493 
494   if( list_desc == NULL )
495     return( LST_ERROR );
496 
497   if( list_desc -> head == NULL )
498     return( LST_ERROR );
499 
500   if( list_desc -> head -> next == NULL ) {
501 
502     SysFree( list_desc -> head -> record );
503     SysFree( list_desc -> head );
504 
505     list_desc -> head    = NULL;
506     list_desc -> tail    = NULL;
507     list_desc -> current = NULL;
508 
509   } else {
510 
511     /* Remove the data for the record. */
512     SysFree( list_desc -> head -> record );
513 
514     if( list_desc -> current == list_desc -> head )
515       list_desc -> current = list_desc -> head -> next;
516 
517     list_desc -> head = list_desc -> head -> next;
518 
519     /* Remove the record. */
520     SysFree( list_desc -> head -> previous );
521 
522     list_desc -> head -> previous = NULL;
523 
524   } /* if */
525 
526   list_desc -> elements--;
527 
528 
529   return( LST_OK );
530 
531 } /* LstLinkDeleteFirst */
532 
533 
534 /*----------------------------------------------------------------------*/
535 
536 LST_STATUS
LstLinkDeleteLast(LST_DESC_TYPE list_desc)537   LstLinkDeleteLast( LST_DESC_TYPE  list_desc )
538 {
539 
540   /* Code. */
541 
542   if( list_desc == NULL )
543     return( LST_ERROR );
544 
545   if( list_desc -> tail == NULL )
546     return( LST_ERROR );
547 
548   if( list_desc -> tail -> previous == NULL ) {
549 
550     SysFree( list_desc -> tail -> record );
551     SysFree( list_desc -> tail );
552 
553     list_desc -> head    = NULL;
554     list_desc -> tail    = NULL;
555     list_desc -> current = NULL;
556 
557   } else {
558 
559     /* Remove the data for the record. */
560     SysFree( list_desc -> tail -> record );
561 
562     if( list_desc -> current == list_desc -> tail )
563       list_desc -> current = list_desc -> tail -> previous;
564 
565     list_desc -> tail = list_desc -> tail -> previous;
566 
567     /* Remove the record. */
568     SysFree( list_desc -> tail -> next );
569 
570     list_desc -> tail -> next = NULL;
571 
572   } /* if */
573 
574   list_desc -> elements--;
575 
576 
577   return( LST_OK );
578 
579 } /* LstLinkDeleteLast */
580 
581 
582 /*----------------------------------------------------------------------*/
583 
584 LST_STATUS
LstLinkDeleteCurrent(LST_DESC_TYPE list_desc)585   LstLinkDeleteCurrent( LST_DESC_TYPE  list_desc )
586 {
587 
588   /* Variables. */
589   LST_RECORD_TYPE  *temp_ref;
590 
591 
592   /* Code. */
593 
594   if( list_desc == NULL )
595     return( LST_ERROR );
596 
597   if( list_desc -> current == NULL )
598     return( LST_ERROR );
599 
600   /* Is this the first element? */
601   if( list_desc -> current -> previous == NULL )
602     return( LstLinkDeleteFirst( list_desc ) );
603 
604   /* Is this the last element? */
605   if( list_desc -> current -> next == NULL )
606     return( LstLinkDeleteLast( list_desc ) );
607 
608 
609   /* Remove the data for the record. */
610   SysFree( list_desc -> current -> record );
611 
612   list_desc -> current -> next -> previous =
613     list_desc -> current -> previous;
614 
615   list_desc -> current -> previous -> next =
616     list_desc -> current -> next;
617 
618   /* Before the node can be deleted, keep a reference. */
619   temp_ref = list_desc -> current;
620 
621   list_desc -> current = list_desc -> current -> next;
622 
623   SysFree( temp_ref );
624 
625   list_desc -> elements--;
626 
627 
628   return( LST_OK );
629 
630 } /* LstLinkDeleteCurrent */
631 
632 
633 /*----------------------------------------------------------------------*/
634 
635 LST_STATUS
LstLinkGetCurrent(LST_DESC_TYPE list_desc,void * record)636   LstLinkGetCurrent( LST_DESC_TYPE  list_desc,
637                      void           *record )
638 {
639 
640   /* Code. */
641 
642   if( list_desc == NULL )
643     return( LST_ERROR );
644 
645   if( list_desc -> current == NULL )
646     return( LST_ERROR );
647 
648   memcpy( record, list_desc -> current -> record, list_desc -> record_size );
649 
650 
651   return( LST_OK );
652 
653 } /* LstLinkGetCurrent */
654 
655 
656 /*----------------------------------------------------------------------*/
657 
658 void
LstLinkGetCurrentRef(LST_DESC_TYPE list_desc)659   *LstLinkGetCurrentRef( LST_DESC_TYPE  list_desc )
660 {
661 
662   /* Code. */
663 
664   if( list_desc == NULL )
665     return( (void *)NULL );
666 
667   if( list_desc -> current == NULL )
668     return( (void *)NULL );
669 
670 
671   return( (void *) list_desc -> current -> record );
672 
673 } /* LstLinkGetCurrentRef */
674 
675 
676 /*----------------------------------------------------------------------*/
677 
678 LST_STATUS
LstLinkGetFirst(LST_DESC_TYPE list_desc,void * record)679   LstLinkGetFirst( LST_DESC_TYPE  list_desc,
680                    void           *record )
681 {
682 
683   /* Code. */
684 
685   if( list_desc == NULL )
686     return( LST_ERROR );
687 
688   if( list_desc -> head == NULL )
689     return( LST_ERROR );
690 
691   memcpy( record, list_desc -> head -> record, list_desc -> record_size );
692 
693 
694   return( LST_OK );
695 
696 } /* LstLinkGetFirst */
697 
698 
699 /*----------------------------------------------------------------------*/
700 
701 LST_STATUS
LstLinkGetLast(LST_DESC_TYPE list_desc,void * record)702   LstLinkGetLast( LST_DESC_TYPE  list_desc,
703                   void           *record )
704 {
705 
706   /* Code. */
707 
708   if( list_desc == NULL )
709     return( LST_ERROR );
710 
711   if( list_desc -> tail == NULL )
712     return( LST_ERROR );
713 
714   memcpy( record, list_desc -> tail -> record, list_desc -> record_size );
715 
716 
717   return( LST_OK );
718 
719 } /* LstLinkGetLast */
720 
721 
722 /*----------------------------------------------------------------------*/
723 
724 LST_STATUS
LstLinkSetCurrent(LST_DESC_TYPE list_desc,void * record)725   LstLinkSetCurrent( LST_DESC_TYPE  list_desc,
726                      void           *record )
727 {
728 
729   /* Code. */
730 
731   if( list_desc == NULL )
732     return( LST_ERROR );
733 
734   if( list_desc -> current == NULL )
735     return( LST_ERROR );
736 
737   memcpy( list_desc -> current -> record, record, list_desc -> record_size );
738 
739 
740   return( LST_OK );
741 
742 } /* LstLinkSetCurrent */
743 
744 
745 /*----------------------------------------------------------------------*/
746 
747 LST_STATUS
LstLinkSetFirst(LST_DESC_TYPE list_desc,void * record)748   LstLinkSetFirst( LST_DESC_TYPE  list_desc,
749                    void           *record )
750 {
751 
752   /* Code. */
753 
754   if( list_desc == NULL )
755     return( LST_ERROR );
756 
757   if( list_desc -> head == NULL )
758     return( LST_ERROR );
759 
760   memcpy( list_desc -> head -> record, record, list_desc -> record_size );
761 
762 
763   return( LST_OK );
764 
765 } /* LstLinkSetFirst */
766 
767 
768 /*----------------------------------------------------------------------*/
769 
770 LST_STATUS
LstLinkSetLast(LST_DESC_TYPE list_desc,void * record)771   LstLinkSetLast( LST_DESC_TYPE  list_desc,
772                   void           *record )
773 {
774 
775   /* Code. */
776 
777   if( list_desc == NULL )
778     return( LST_ERROR );
779 
780   if( list_desc -> tail == NULL )
781     return( LST_ERROR );
782 
783   memcpy( list_desc -> tail -> record, record, list_desc -> record_size );
784 
785 
786   return( LST_OK );
787 
788 } /* LstLinkSetLast */
789 
790 
791 /*----------------------------------------------------------------------*/
792 
793 LST_STATUS
LstLinkSearchFirst(LST_DESC_TYPE list_desc,void * element,EQUALS_FUNC_TYPE equals_func)794   LstLinkSearchFirst( LST_DESC_TYPE     list_desc,
795                       void              *element,
796                       EQUALS_FUNC_TYPE  equals_func )
797 {
798 
799   /* Variables. */
800   EQUALS_FUNC_TYPE  compare_func;
801   LST_RECORD_TYPE   *node_ref;
802 
803 
804   /* Code. */
805 
806   if( list_desc == NULL )
807     return( LST_ERROR );
808 
809   if( list_desc -> head == NULL )
810     return( LST_NOT_FOUND );
811 
812   /* Use the supplied compare function? */
813   if( equals_func != NULL )
814     compare_func = equals_func;
815   else if( list_desc -> equals_func != NULL )
816     compare_func = list_desc -> equals_func;
817   else
818     return( LST_NOT_FOUND );
819 
820   node_ref = list_desc -> head;
821 
822   /* Search the element in the list. */
823   while( node_ref != NULL ) {
824 
825     if( ( *compare_func )( node_ref -> record, element ) == LST_EQUAL ) {
826       list_desc -> current = node_ref;
827       return( LST_OK );
828     }
829 
830     node_ref = node_ref -> next;
831 
832   } /* while */
833 
834 
835   return( LST_NOT_FOUND );
836 
837 } /* LstLinkSearchFirst */
838 
839 
840 /*----------------------------------------------------------------------*/
841 
842 LST_STATUS
LstLinkSearchLast(LST_DESC_TYPE list_desc,void * element,EQUALS_FUNC_TYPE equals_func)843   LstLinkSearchLast( LST_DESC_TYPE     list_desc,
844                      void              *element,
845                      EQUALS_FUNC_TYPE  equals_func )
846 {
847 
848   /* Variables. */
849   EQUALS_FUNC_TYPE  compare_func;
850   LST_RECORD_TYPE   *node_ref;
851 
852 
853   /* Code. */
854 
855   if( list_desc == NULL )
856     return( LST_ERROR );
857 
858   if( list_desc -> tail == NULL )
859     return( LST_NOT_FOUND );
860 
861   /* Use the supplied compare function? */
862   if( equals_func != NULL )
863     compare_func = equals_func;
864   else if( list_desc -> equals_func != NULL )
865     compare_func = list_desc -> equals_func;
866   else
867     return( LST_NOT_FOUND );
868 
869   node_ref = list_desc -> tail;
870 
871   /* Search the element in the list. */
872   while( node_ref != NULL ) {
873 
874     if( ( *compare_func )( node_ref -> record, element ) == LST_EQUAL ) {
875       list_desc -> current = node_ref;
876       return( LST_OK );
877     }
878 
879     node_ref = node_ref -> previous;
880 
881   } /* while */
882 
883 
884   return( LST_NOT_FOUND );
885 
886 } /* LstLinkSearchLast */
887 
888 
889 /*----------------------------------------------------------------------*/
890 
891 LST_STATUS
LstLinkSearchCurrent(LST_DESC_TYPE list_desc,void * element,LST_DIRECTION direction,EQUALS_FUNC_TYPE equals_func)892   LstLinkSearchCurrent( LST_DESC_TYPE     list_desc,
893                         void              *element,
894                         LST_DIRECTION     direction,
895                         EQUALS_FUNC_TYPE  equals_func )
896 {
897 
898   /* Variables. */
899   EQUALS_FUNC_TYPE  compare_func;
900   LST_RECORD_TYPE   *node_ref;
901 
902 
903   /* Code. */
904 
905   if( list_desc == NULL )
906     return( LST_ERROR );
907 
908   if( list_desc -> current == NULL )
909     return( LST_NOT_FOUND );
910 
911   /* Use the supplied compare function? */
912   if( equals_func != NULL )
913     compare_func = equals_func;
914   else if( list_desc -> equals_func != NULL )
915     compare_func = list_desc -> equals_func;
916   else
917     return( LST_NOT_FOUND );
918 
919   node_ref = list_desc -> current;
920 
921   /* Search the element in the list. */
922   while( node_ref != NULL ) {
923 
924     if( ( *compare_func )( node_ref -> record, element ) == LST_EQUAL ) {
925       list_desc -> current = node_ref;
926       return( LST_OK );
927     }
928 
929     if( direction == LST_FORWARD )
930       node_ref = node_ref -> next;
931     else
932       node_ref = node_ref -> previous;
933 
934   } /* while */
935 
936 
937   return( LST_NOT_FOUND );
938 
939 } /* LstLinkSearchCurrent */
940 
941 
942 /*----------------------------------------------------------------------*/
943 
944 int
LstLinkElements(LST_DESC_TYPE list_desc)945   LstLinkElements( LST_DESC_TYPE list_desc )
946 {
947 
948   /* Code. */
949 
950   return( list_desc -> elements );
951 
952 } /* LstLinkElements */
953 
954 
955