Leptonica  1.77.0
Image processing and image analysis suite
list.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  -
4  - Redistribution and use in source and binary forms, with or without
5  - modification, are permitted provided that the following conditions
6  - are met:
7  - 1. Redistributions of source code must retain the above copyright
8  - notice, this list of conditions and the following disclaimer.
9  - 2. Redistributions in binary form must reproduce the above
10  - copyright notice, this list of conditions and the following
11  - disclaimer in the documentation and/or other materials
12  - provided with the distribution.
13  -
14  - THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
15  - ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
16  - LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
17  - A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL ANY
18  - CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
19  - EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
20  - PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
21  - PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22  - OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23  - NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24  - SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25  *====================================================================*/
26 
213 #include <string.h>
214 #include "allheaders.h"
215 
216 
217 /*---------------------------------------------------------------------*
218  * Inserting and removing elements *
219  *---------------------------------------------------------------------*/
235 void
237 {
238 DLLIST *elem, *next, *head;
239 
240  PROCNAME("listDestroy");
241 
242  if (phead == NULL) {
243  L_WARNING("ptr address is null!\n", procName);
244  return;
245  }
246 
247  if ((head = *phead) == NULL)
248  return;
249 
250  for (elem = head; elem; elem = next) {
251  if (elem->data)
252  L_WARNING("list data ptr is not null\n", procName);
253  next = elem->next;
254  LEPT_FREE(elem);
255  }
256  *phead = NULL;
257  return;
258 }
259 
260 
276 l_ok
278  void *data)
279 {
280 DLLIST *cell, *head;
281 
282  PROCNAME("listAddToHead");
283 
284  if (!phead)
285  return ERROR_INT("&head not defined", procName, 1);
286  head = *phead;
287  if (!data)
288  return ERROR_INT("data not defined", procName, 1);
289 
290  if ((cell = (DLLIST *)LEPT_CALLOC(1, sizeof(DLLIST))) == NULL)
291  return ERROR_INT("cell not made", procName, 1);
292  cell->data = data;
293 
294  if (!head) { /* start the list; initialize the ptrs */
295  cell->prev = NULL;
296  cell->next = NULL;
297  } else {
298  cell->prev = NULL;
299  cell->next = head;
300  head->prev = cell;
301  }
302  *phead = cell;
303  return 0;
304 }
305 
306 
330 l_ok
332  DLLIST **ptail,
333  void *data)
334 {
335 DLLIST *cell, *head, *tail;
336 
337  PROCNAME("listAddToTail");
338 
339  if (!phead)
340  return ERROR_INT("&head not defined", procName, 1);
341  head = *phead;
342  if (!ptail)
343  return ERROR_INT("&tail not defined", procName, 1);
344  if (!data)
345  return ERROR_INT("data not defined", procName, 1);
346 
347  if ((cell = (DLLIST *)LEPT_CALLOC(1, sizeof(DLLIST))) == NULL)
348  return ERROR_INT("cell not made", procName, 1);
349  cell->data = data;
350 
351  if (!head) { /* Start the list and initialize the ptrs. *ptail
352  * should also have been initialized to NULL */
353  cell->prev = NULL;
354  cell->next = NULL;
355  *phead = cell;
356  *ptail = cell;
357  } else {
358  if ((tail = *ptail) == NULL)
359  tail = listFindTail(head);
360  cell->prev = tail;
361  cell->next = NULL;
362  tail->next = cell;
363  *ptail = cell;
364  }
365 
366  return 0;
367 }
368 
369 
393 l_ok
395  DLLIST *elem,
396  void *data)
397 {
398 DLLIST *cell, *head;
399 
400  PROCNAME("listInsertBefore");
401 
402  if (!phead)
403  return ERROR_INT("&head not defined", procName, 1);
404  head = *phead;
405  if (!data)
406  return ERROR_INT("data not defined", procName, 1);
407  if ((!head && elem) || (head && !elem))
408  return ERROR_INT("head and elem not consistent", procName, 1);
409 
410  /* New cell to insert */
411  if ((cell = (DLLIST *)LEPT_CALLOC(1, sizeof(DLLIST))) == NULL)
412  return ERROR_INT("cell not made", procName, 1);
413  cell->data = data;
414 
415  if (!head) { /* start the list; initialize the ptrs */
416  cell->prev = NULL;
417  cell->next = NULL;
418  *phead = cell;
419  } else if (head == elem) { /* insert before head of list */
420  cell->prev = NULL;
421  cell->next = head;
422  head->prev = cell;
423  *phead = cell;
424  } else { /* insert before elem and after head of list */
425  cell->prev = elem->prev;
426  cell->next = elem;
427  elem->prev->next = cell;
428  elem->prev = cell;
429  }
430  return 0;
431 }
432 
433 
458 l_ok
460  DLLIST *elem,
461  void *data)
462 {
463 DLLIST *cell, *head;
464 
465  PROCNAME("listInsertAfter");
466 
467  if (!phead)
468  return ERROR_INT("&head not defined", procName, 1);
469  head = *phead;
470  if (!data)
471  return ERROR_INT("data not defined", procName, 1);
472  if ((!head && elem) || (head && !elem))
473  return ERROR_INT("head and elem not consistent", procName, 1);
474 
475  /* New cell to insert */
476  if ((cell = (DLLIST *)LEPT_CALLOC(1, sizeof(DLLIST))) == NULL)
477  return ERROR_INT("cell not made", procName, 1);
478  cell->data = data;
479 
480  if (!head) { /* start the list; initialize the ptrs */
481  cell->prev = NULL;
482  cell->next = NULL;
483  *phead = cell;
484  } else if (elem->next == NULL) { /* insert after last */
485  cell->prev = elem;
486  cell->next = NULL;
487  elem->next = cell;
488  } else { /* insert after elem and before the end */
489  cell->prev = elem;
490  cell->next = elem->next;
491  elem->next->prev = cell;
492  elem->next = cell;
493  }
494  return 0;
495 }
496 
497 
513 void *
515  DLLIST *elem)
516 {
517 void *data;
518 DLLIST *head;
519 
520  PROCNAME("listRemoveElement");
521 
522  if (!phead)
523  return (void *)ERROR_PTR("&head not defined", procName, NULL);
524  head = *phead;
525  if (!head)
526  return (void *)ERROR_PTR("head not defined", procName, NULL);
527  if (!elem)
528  return (void *)ERROR_PTR("elem not defined", procName, NULL);
529 
530  data = elem->data;
531 
532  if (head->next == NULL) { /* only one */
533  if (elem != head)
534  return (void *)ERROR_PTR("elem must be head", procName, NULL);
535  *phead = NULL;
536  } else if (head == elem) { /* first one */
537  elem->next->prev = NULL;
538  *phead = elem->next;
539  } else if (elem->next == NULL) { /* last one */
540  elem->prev->next = NULL;
541  } else { /* neither the first nor the last one */
542  elem->next->prev = elem->prev;
543  elem->prev->next = elem->next;
544  }
545 
546  LEPT_FREE(elem);
547  return data;
548 }
549 
550 
565 void *
567 {
568 DLLIST *head;
569 void *data;
570 
571  PROCNAME("listRemoveFromHead");
572 
573  if (!phead)
574  return (void *)ERROR_PTR("&head not defined", procName, NULL);
575  if ((head = *phead) == NULL)
576  return (void *)ERROR_PTR("head not defined", procName, NULL);
577 
578  if (head->next == NULL) { /* only one */
579  *phead = NULL;
580  } else {
581  head->next->prev = NULL;
582  *phead = head->next;
583  }
584 
585  data = head->data;
586  LEPT_FREE(head);
587  return data;
588 }
589 
590 
613 void *
615  DLLIST **ptail)
616 {
617 DLLIST *head, *tail;
618 void *data;
619 
620  PROCNAME("listRemoveFromTail");
621 
622  if (!phead)
623  return (void *)ERROR_PTR("&head not defined", procName, NULL);
624  if ((head = *phead) == NULL)
625  return (void *)ERROR_PTR("head not defined", procName, NULL);
626  if (!ptail)
627  return (void *)ERROR_PTR("&tail not defined", procName, NULL);
628  if ((tail = *ptail) == NULL)
629  tail = listFindTail(head);
630 
631  if (head->next == NULL) { /* only one */
632  *phead = NULL;
633  *ptail = NULL;
634  } else {
635  tail->prev->next = NULL;
636  *ptail = tail->prev;
637  }
638 
639  data = tail->data;
640  LEPT_FREE(tail);
641  return data;
642 }
643 
644 
645 
646 /*---------------------------------------------------------------------*
647  * Other list operations *
648  *---------------------------------------------------------------------*/
667 DLLIST *
669  void *data)
670 {
671 DLLIST *cell;
672 
673  PROCNAME("listFindElement");
674 
675  if (!head)
676  return (DLLIST *)ERROR_PTR("head not defined", procName, NULL);
677  if (!data)
678  return (DLLIST *)ERROR_PTR("data not defined", procName, NULL);
679 
680  for (cell = head; cell; cell = cell->next) {
681  if (cell->data == data)
682  return cell;
683  }
684 
685  return NULL;
686 }
687 
688 
695 DLLIST *
697 {
698 DLLIST *cell;
699 
700  PROCNAME("listFindTail");
701 
702  if (!head)
703  return (DLLIST *)ERROR_PTR("head not defined", procName, NULL);
704 
705  for (cell = head; cell; cell = cell->next) {
706  if (cell->next == NULL)
707  return cell;
708  }
709 
710  return (DLLIST *)ERROR_PTR("tail not found !!", procName, NULL);
711 }
712 
713 
720 l_int32
722 {
723 l_int32 count;
724 DLLIST *elem;
725 
726  PROCNAME("listGetCount");
727 
728  if (!head)
729  return ERROR_INT("head not defined", procName, 0);
730 
731  count = 0;
732  for (elem = head; elem; elem = elem->next)
733  count++;
734 
735  return count;
736 }
737 
738 
750 l_ok
752 {
753 void *obj; /* whatever */
754 DLLIST *head, *rhead;
755 
756  PROCNAME("listReverse");
757 
758  if (!phead)
759  return ERROR_INT("&head not defined", procName, 1);
760  if ((head = *phead) == NULL)
761  return ERROR_INT("head not defined", procName, 1);
762 
763  rhead = NULL;
764  while (head) {
765  obj = listRemoveFromHead(&head);
766  listAddToHead(&rhead, obj);
767  }
768 
769  *phead = rhead;
770  return 0;
771 }
772 
773 
787 l_ok
788 listJoin(DLLIST **phead1,
789  DLLIST **phead2)
790 {
791 void *obj;
792 DLLIST *head1, *head2, *tail1;
793 
794  PROCNAME("listJoin");
795 
796  if (!phead1)
797  return ERROR_INT("&head1 not defined", procName, 1);
798  if (!phead2)
799  return ERROR_INT("&head2 not defined", procName, 1);
800 
801  /* If no list2, just return list1 unchanged */
802  if ((head2 = *phead2) == NULL)
803  return 0;
804 
805  /* If no list1, just return list2 */
806  if ((head1 = *phead1) == NULL) {
807  *phead1 = head2;
808  *phead2 = NULL;
809  return 0;
810  }
811 
812  /* General case for concatenation into list 1 */
813  tail1 = listFindTail(head1);
814  while (head2) {
815  obj = listRemoveFromHead(&head2);
816  listAddToTail(&head1, &tail1, obj);
817  }
818  *phead2 = NULL;
819  return 0;
820 }
void listDestroy(DLLIST **phead)
listDestroy()
Definition: list.c:236
void * listRemoveFromHead(DLLIST **phead)
listRemoveFromHead()
Definition: list.c:566
DLLIST * listFindTail(DLLIST *head)
listFindTail()
Definition: list.c:696
l_int32 listGetCount(DLLIST *head)
listGetCount()
Definition: list.c:721
void * listRemoveFromTail(DLLIST **phead, DLLIST **ptail)
listRemoveFromTail()
Definition: list.c:614
void * listRemoveElement(DLLIST **phead, DLLIST *elem)
listRemoveElement()
Definition: list.c:514
l_ok listReverse(DLLIST **phead)
listReverse()
Definition: list.c:751
l_ok listInsertBefore(DLLIST **phead, DLLIST *elem, void *data)
listInsertBefore()
Definition: list.c:394
l_ok listAddToTail(DLLIST **phead, DLLIST **ptail, void *data)
listAddToTail()
Definition: list.c:331
l_ok listAddToHead(DLLIST **phead, void *data)
listAddToHead()
Definition: list.c:277
l_ok listInsertAfter(DLLIST **phead, DLLIST *elem, void *data)
listInsertAfter()
Definition: list.c:459
l_ok listJoin(DLLIST **phead1, DLLIST **phead2)
listJoin()
Definition: list.c:788
DLLIST * listFindElement(DLLIST *head, void *data)
listFindElement()
Definition: list.c:668