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