Leptonica  1.73
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_int32
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_int32
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 
392 l_int32
394  DLLIST *elem,
395  void *data)
396 {
397 DLLIST *cell, *head;
398 
399  PROCNAME("listInsertBefore");
400 
401  if (!phead)
402  return ERROR_INT("&head not defined", procName, 1);
403  head = *phead;
404  if (!data)
405  return ERROR_INT("data not defined", procName, 1);
406  if ((!head && elem) || (head && !elem))
407  return ERROR_INT("head and elem not consistent", procName, 1);
408 
409  /* New cell to insert */
410  if ((cell = (DLLIST *)LEPT_CALLOC(1, sizeof(DLLIST))) == NULL)
411  return ERROR_INT("cell not made", procName, 1);
412  cell->data = data;
413 
414  if (!head) { /* start the list; initialize the ptrs */
415  cell->prev = NULL;
416  cell->next = NULL;
417  *phead = cell;
418  } else if (head == elem) { /* insert before head of list */
419  cell->prev = NULL;
420  cell->next = head;
421  head->prev = cell;
422  *phead = cell;
423  } else { /* insert before elem and after head of list */
424  cell->prev = elem->prev;
425  cell->next = elem;
426  elem->prev->next = cell;
427  elem->prev = cell;
428  }
429  return 0;
430 }
431 
432 
455 l_int32
457  DLLIST *elem,
458  void *data)
459 {
460 DLLIST *cell, *head;
461 
462  PROCNAME("listInsertAfter");
463 
464  if (!phead)
465  return ERROR_INT("&head not defined", procName, 1);
466  head = *phead;
467  if (!data)
468  return ERROR_INT("data not defined", procName, 1);
469  if ((!head && elem) || (head && !elem))
470  return ERROR_INT("head and elem not consistent", procName, 1);
471 
472  /* New cell to insert */
473  if ((cell = (DLLIST *)LEPT_CALLOC(1, sizeof(DLLIST))) == NULL)
474  return ERROR_INT("cell not made", procName, 1);
475  cell->data = data;
476 
477  if (!head) { /* start the list; initialize the ptrs */
478  cell->prev = NULL;
479  cell->next = NULL;
480  *phead = cell;
481  } else if (elem->next == NULL) { /* insert after last */
482  cell->prev = elem;
483  cell->next = NULL;
484  elem->next = cell;
485  } else { /* insert after elem and before the end */
486  cell->prev = elem;
487  cell->next = elem->next;
488  elem->next->prev = cell;
489  elem->next = cell;
490  }
491  return 0;
492 }
493 
494 
510 void *
512  DLLIST *elem)
513 {
514 void *data;
515 DLLIST *head;
516 
517  PROCNAME("listRemoveElement");
518 
519  if (!phead)
520  return (void *)ERROR_PTR("&head not defined", procName, NULL);
521  head = *phead;
522  if (!head)
523  return (void *)ERROR_PTR("head not defined", procName, NULL);
524  if (!elem)
525  return (void *)ERROR_PTR("elem not defined", procName, NULL);
526 
527  data = elem->data;
528 
529  if (head->next == NULL) { /* only one */
530  if (elem != head)
531  return (void *)ERROR_PTR("elem must be head", procName, NULL);
532  *phead = NULL;
533  } else if (head == elem) { /* first one */
534  elem->next->prev = NULL;
535  *phead = elem->next;
536  } else if (elem->next == NULL) { /* last one */
537  elem->prev->next = NULL;
538  } else { /* neither the first nor the last one */
539  elem->next->prev = elem->prev;
540  elem->prev->next = elem->next;
541  }
542 
543  LEPT_FREE(elem);
544  return data;
545 }
546 
547 
562 void *
564 {
565 DLLIST *head;
566 void *data;
567 
568  PROCNAME("listRemoveFromHead");
569 
570  if (!phead)
571  return (void *)ERROR_PTR("&head not defined", procName, NULL);
572  if ((head = *phead) == NULL)
573  return (void *)ERROR_PTR("head not defined", procName, NULL);
574 
575  if (head->next == NULL) { /* only one */
576  *phead = NULL;
577  } else {
578  head->next->prev = NULL;
579  *phead = head->next;
580  }
581 
582  data = head->data;
583  LEPT_FREE(head);
584  return data;
585 }
586 
587 
610 void *
612  DLLIST **ptail)
613 {
614 DLLIST *head, *tail;
615 void *data;
616 
617  PROCNAME("listRemoveFromTail");
618 
619  if (!phead)
620  return (void *)ERROR_PTR("&head not defined", procName, NULL);
621  if ((head = *phead) == NULL)
622  return (void *)ERROR_PTR("head not defined", procName, NULL);
623  if (!ptail)
624  return (void *)ERROR_PTR("&tail not defined", procName, NULL);
625  if ((tail = *ptail) == NULL)
626  tail = listFindTail(head);
627 
628  if (head->next == NULL) { /* only one */
629  *phead = NULL;
630  *ptail = NULL;
631  } else {
632  tail->prev->next = NULL;
633  *ptail = tail->prev;
634  }
635 
636  data = tail->data;
637  LEPT_FREE(tail);
638  return data;
639 }
640 
641 
642 
643 /*---------------------------------------------------------------------*
644  * Other list operations *
645  *---------------------------------------------------------------------*/
664 DLLIST *
666  void *data)
667 {
668 DLLIST *cell;
669 
670  PROCNAME("listFindElement");
671 
672  if (!head)
673  return (DLLIST *)ERROR_PTR("head not defined", procName, NULL);
674  if (!data)
675  return (DLLIST *)ERROR_PTR("data not defined", procName, NULL);
676 
677  for (cell = head; cell; cell = cell->next) {
678  if (cell->data == data)
679  return cell;
680  }
681 
682  return NULL;
683 }
684 
685 
692 DLLIST *
694 {
695 DLLIST *cell;
696 
697  PROCNAME("listFindTail");
698 
699  if (!head)
700  return (DLLIST *)ERROR_PTR("head not defined", procName, NULL);
701 
702  for (cell = head; cell; cell = cell->next) {
703  if (cell->next == NULL)
704  return cell;
705  }
706 
707  return (DLLIST *)ERROR_PTR("tail not found !!", procName, NULL);
708 }
709 
710 
717 l_int32
719 {
720 l_int32 count;
721 DLLIST *elem;
722 
723  PROCNAME("listGetCount");
724 
725  if (!head)
726  return ERROR_INT("head not defined", procName, 0);
727 
728  count = 0;
729  for (elem = head; elem; elem = elem->next)
730  count++;
731 
732  return count;
733 }
734 
735 
747 l_int32
749 {
750 void *obj; /* whatever */
751 DLLIST *head, *rhead;
752 
753  PROCNAME("listReverse");
754 
755  if (!phead)
756  return ERROR_INT("&head not defined", procName, 1);
757  if ((head = *phead) == NULL)
758  return ERROR_INT("head not defined", procName, 1);
759 
760  rhead = NULL;
761  while (head) {
762  obj = listRemoveFromHead(&head);
763  listAddToHead(&rhead, obj);
764  }
765 
766  *phead = rhead;
767  return 0;
768 }
769 
770 
784 l_int32
785 listJoin(DLLIST **phead1,
786  DLLIST **phead2)
787 {
788 void *obj;
789 DLLIST *head1, *head2, *tail1;
790 
791  PROCNAME("listJoin");
792 
793  if (!phead1)
794  return ERROR_INT("&head1 not defined", procName, 1);
795  if (!phead2)
796  return ERROR_INT("&head2 not defined", procName, 1);
797 
798  /* If no list2, just return list1 unchanged */
799  if ((head2 = *phead2) == NULL)
800  return 0;
801 
802  /* If no list1, just return list2 */
803  if ((head1 = *phead1) == NULL) {
804  *phead1 = head2;
805  *phead2 = NULL;
806  return 0;
807  }
808 
809  /* General case for concatenation into list 1 */
810  tail1 = listFindTail(head1);
811  while (head2) {
812  obj = listRemoveFromHead(&head2);
813  listAddToTail(&head1, &tail1, obj);
814  }
815  *phead2 = NULL;
816  return 0;
817 }
l_int32 listInsertAfter(DLLIST **phead, DLLIST *elem, void *data)
listInsertAfter()
Definition: list.c:456
void listDestroy(DLLIST **phead)
listDestroy()
Definition: list.c:236
l_int32 listAddToHead(DLLIST **phead, void *data)
listAddToHead()
Definition: list.c:277
void * listRemoveFromHead(DLLIST **phead)
listRemoveFromHead()
Definition: list.c:563
DLLIST * listFindTail(DLLIST *head)
listFindTail()
Definition: list.c:693
l_int32 listJoin(DLLIST **phead1, DLLIST **phead2)
listJoin()
Definition: list.c:785
l_int32 listGetCount(DLLIST *head)
listGetCount()
Definition: list.c:718
void * listRemoveFromTail(DLLIST **phead, DLLIST **ptail)
listRemoveFromTail()
Definition: list.c:611
void * listRemoveElement(DLLIST **phead, DLLIST *elem)
listRemoveElement()
Definition: list.c:511
l_int32 listReverse(DLLIST **phead)
listReverse()
Definition: list.c:748
l_int32 listInsertBefore(DLLIST **phead, DLLIST *elem, void *data)
listInsertBefore()
Definition: list.c:393
DLLIST * listFindElement(DLLIST *head, void *data)
listFindElement()
Definition: list.c:665
l_int32 listAddToTail(DLLIST **phead, DLLIST **ptail, void *data)
listAddToTail()
Definition: list.c:331