w32tex
About: TeX Live provides a comprehensive TeX system including all the major TeX-related programs, macro packages, and fonts that are free software. Windows sources.
  Fossies Dox: w32tex-src.tar.xz  ("unofficial" and yet experimental doxygen-generated source code documentation)  

list.c
Go to the documentation of this file.
1 /*====================================================================*
2  - Copyright (C) 2001 Leptonica. All rights reserved.
3  - This software is distributed in the hope that it will be
4  - useful, but with NO WARRANTY OF ANY KIND.
5  - No author or distributor accepts responsibility to anyone for the
6  - consequences of using this software, or for whether it serves any
7  - particular purpose or works at all, unless he or she says so in
8  - writing. Everyone is granted permission to copy, modify and
9  - redistribute this source code, for commercial or non-commercial
10  - purposes, with the following restrictions: (1) the origin of this
11  - source code must not be misrepresented; (2) modified versions must
12  - be plainly marked as such; and (3) this notice may not be removed
13  - or altered from any source or modified source distribution.
14  *====================================================================*/
15 
16 /*
17  * list.c
18  *
19  * Inserting and removing elements
20  *
21  * void listDestroy()
22  * DLLIST *listAddToHead()
23  * l_int32 listAddToTail()
24  * l_int32 listInsertBefore()
25  * l_int32 listInsertAfter()
26  * void *listRemoveElement()
27  * void *listRemoveFromHead()
28  * void *listRemoveFromTail()
29  *
30  * Other list operations
31  *
32  * DLLIST *listFindElement()
33  * DLLIST *listFindTail()
34  * l_int32 listGetCount()
35  * l_int32 listReverse()
36  * DLLIST *listJoin()
37  *
38  * Lists are much harder to handle than arrays. There is
39  * more overhead for the programmer, both cognitive and
40  * codewise, and more likelihood that an error can be made.
41  * For that reason, lists should only be used when it is
42  * inefficient to use arrays, such as when elements are
43  * routinely inserted or deleted from inside arrays whose
44  * average size is greater than about 10.
45  *
46  * A list of data structures can be implemented in a number
47  * of ways. The two most popular are:
48  *
49  * (1) The list can be composed of a linked list of
50  * pointer cells ("cons cells"), where the data structures
51  * are hung off the cells. This is more difficult
52  * to use because you have to keep track of both
53  * your hanging data and the cell structures.
54  * It requires 3 pointers for every data structure
55  * that is put in a list. There is no problem
56  * cloning (using reference counts) for structures that
57  * are put in such a list. We implement lists by this
58  * method here.
59  *
60  * (2) The list pointers can be inserted directly into
61  * the data structures. This is easy to implement
62  * and easier to use, but it adds 2 ptrs of overhead
63  * to every data structure in which the ptrs are embedded.
64  * It also requires special care not to put the ptrs
65  * in any data that is cloned with a reference count;
66  * else your lists will break.
67  *
68  * Writing C code that uses list pointers explicitly to make
69  * and alter lists is difficult and prone to error.
70  * Consequently, a generic list utility that handles lists
71  * of arbitrary objects and doesn't force the programmer to
72  * touch the "next" and "prev" pointers, is quite useful.
73  * Such functions are provided here. However, the usual
74  * situation requires traversing a list and applying some
75  * function to one or more of the list elements. Macros
76  * for traversing the list are, in general, necessary, to
77  * achieve the goal of invisibly handling all "next" and "prev"
78  * pointers in generic lists. We provide macros for
79  * traversing a list in both forward and reverse directions.
80  *
81  * Because of the typing in C, implementation of a general
82  * list utility requires casting. If macros are used, the
83  * casting can be done implicitly; otherwise, using functions,
84  * some of the casts must be explicit. Fortunately, this
85  * can be implemented with void* so the programmer using
86  * the library will not have to make any casts! (Unless you
87  * compile with g++, in which case the rules on implicit
88  * conversion are more strict.)
89  *
90  * For example, to add an arbitrary data structure foo to the
91  * tail of a list, use
92  * listAddToTail(&head, &tail, pfoo);
93  * where head and tail are list cell ptrs and pfoo is
94  * a pointer to the foo object.
95  * And to remove an arbitrary data structure foo from a
96  * list, when you know the list cell element it is hanging from,
97  * use
98  * pfoo = listRemoveElement(&head, elem)
99  * where head and elem are list cell ptrs and pfoo is a pointer
100  * to the foo object. No casts are required for foo in
101  * either direction in ANSI C. (However, casts are
102  * required for ANSI C++).
103  *
104  * We use lists that are composed of doubly-linked
105  * cells with data structures hanging off the cells.
106  * We use doubly-linked cells to simplify insertion
107  * and deletion, and to allow operations to proceed in either
108  * direction along the list. With doubly-linked lists,
109  * it is tempting to make them circular, by setting head->prev
110  * to the tail of the list and tail->next to the head.
111  * The circular list costs nothing extra in storage, and
112  * allows operations to proceed from either end of the list
113  * with equal speed. However, the circular link adds
114  * cognitive overhead for the application programmer in
115  * general, and it greatly complicates list traversal when
116  * arbitrary list elements can be added or removed as you
117  * move through. It can be done, but in the spirit of
118  * simplicity, we avoid the temptation. The price to be paid
119  * is the extra cost to find the tail of a list -- a full
120  * traversal -- before the tail can be used. This is a
121  * cheap price to pay to avoid major headaches and buggy code.
122  *
123  * When you are only applying some function to each element
124  * in a list, you can go either forwards or backwards.
125  * To run through a list forwards, use:
126  *
127  * for (elem = head; elem; elem = nextelem) {
128  * nextelem = elem->next; (in case we destroy elem)
129  * <do something with elem->data>
130  * }
131  *
132  * To run through a list backwards, find the tail and use:
133  *
134  * for (elem = tail; elem; elem = prevelem) {
135  # prevelem = elem->prev; (in case we destroy elem)
136  * <do something with elem->data>
137  * }
138  *
139  * Even though these patterns are very simple, they are so common
140  * that we've provided macros for them in list.h. Using the
141  * macros, this becomes:
142  *
143  * L_BEGIN_LIST_FORWARD(head, elem)
144  * <do something with elem->data>
145  * L_END_LIST
146  *
147  * L_BEGIN_LIST_REVERSE(tail, elem)
148  * <do something with elem->data>
149  * L_END_LIST
150  *
151  * Note again that with macros, the application programmer does
152  * not need to refer explicitly to next and prev fields. Also,
153  * in the reverse case, note that we do not explicitly
154  * show the head of the list. However, the head of the list
155  * is always in scope, and functions can be called within the
156  * iterator that change the head.
157  *
158  * Some special cases are simpler. For example, when
159  * removing all items from the head of the list, you can use
160  *
161  * while (head) {
162  * obj = listRemoveFromHead(&head);
163  * <do something with obj>
164  * }
165  *
166  * Removing successive elements from the tail is equally simple:
167  *
168  * while (tail) {
169  * obj = listRemoveFromTail(&head, &tail);
170  * <do something with obj>
171  * }
172  *
173  * When removing an arbitrary element from a list, use
174  *
175  * obj = listRemoveElement(&head, elem);
176  *
177  * All the listRemove*() functions hand you the object,
178  * destroy the list cell to which it was attached, and
179  * reset the list pointers if necessary.
180  *
181  * Several other list operations, that do not involve
182  * inserting or removing objects, are also provided.
183  * The function listFindElement() locates a list pointer
184  * by matching the object hanging on it to a given
185  * object. The function listFindTail() gets a handle
186  * to the tail list ptr, allowing backwards traversals of
187  * the list. listGetCount() gives the number of elements
188  * in a list. Functions that reverse a list and concatenate
189  * two lists are also provided.
190  *
191  * These functions can be modified for efficiency in the
192  * situation where there is a large amount of creation and
193  * destruction of list cells. If millions of cells are
194  * made and destroyed, but a relatively small number are
195  * around at any time, the list cells can be stored for
196  * later re-use in a stack (see the generic stack functions
197  * in stack.c).
198  */
199 
200 #include <stdio.h>
201 #include <stdlib.h>
202 #include <string.h>
203 
204 #include "allheaders.h"
205 
206 
207 /*---------------------------------------------------------------------*
208  * Inserting and removing elements *
209  *---------------------------------------------------------------------*/
210 /*!
211  * listDestroy()
212  *
213  * Input: &head (<to be nulled> head of list)
214  * Return: void
215  *
216  * Usage note:
217  * This only destroys the cons cells. Before
218  * destroying the list, you must remove all data
219  * and set the data pointers in each cons cell
220  * to NULL. listDestroy() will give a warning
221  * message for each data ptr that is not NULL.
222  */
223 void
225 {
226 DLLIST *elem, *next, *head;
227 
228  PROCNAME("listDestroy");
229 
230  if (phead == NULL) {
231  L_WARNING("ptr address is null!", procName);
232  return;
233  }
234 
235  if ((head = *phead) == NULL)
236  return;
237 
238  for (elem = head; elem; elem = next) {
239  if (elem->data)
240  L_WARNING("list data ptr is not null", procName);
241  next = elem->next;
242  FREE((void *)elem);
243  }
244  *phead = NULL;
245  return;
246 }
247 
248 
249 /*!
250  * listAddToHead()
251  *
252  * Input: &head (<optional> input head)
253  * data (void* ptr, to be added)
254  * Return: 0 if OK; 1 on error
255  *
256  * Action: this makes a new cell, attaches the data, and
257  * adds the cell to the head of the list.
258  *
259  * Usage note: when consing from NULL, be sure to
260  * initialize head to NULL.
261  */
262 l_int32
264  void *data)
265 {
266 DLLIST *cell, *head;
267 
268  PROCNAME("listAddToHead");
269 
270  if (!phead)
271  return ERROR_INT("&head not defined", procName, 1);
272  head = *phead;
273  if (!data)
274  return ERROR_INT("data not defined", procName, 1);
275 
276  if ((cell = (DLLIST *)CALLOC(1, sizeof(DLLIST))) == NULL)
277  return ERROR_INT("cell not made", procName, 1);
278  cell->data = data;
279 
280  if (!head) { /* start the list; initialize the ptrs */
281  cell->prev = NULL;
282  cell->next = NULL;
283  }
284  else {
285  cell->prev = NULL;
286  cell->next = head;
287  head->prev = cell;
288  }
289  *phead = cell;
290  return 0;
291 }
292 
293 
294 /*!
295  * listAddToTail()
296  *
297  * Input: &head (<may be updated>, head can be null)
298  * &tail (<updated>, tail can be null)
299  * data (void* ptr, to be added)
300  * Return: 0 if OK; 1 on error
301  *
302  * Action: this makes a new cell, attaches the data, and
303  * adds the cell to the tail of the list. Note that
304  * we include the &head to allow the list to be
305  * "cons'd" up from NULL, and we optionally input &tail
306  * to allow the tail to be updated for efficient
307  * sequential operation with this function.
308  *
309  * Usage notes: The function is relying on the fact that
310  * if *phead and/or *ptail are not NULL, then they
311  * are valid addresses. Therefore:
312  * (1) when consing from NULL, be sure to initialize both
313  * head and tail to NULL.
314  * (2) you can use this function with tail == NULL for an
315  * existing list; the tail will be found and updated.
316  */
317 l_int32
319  DLLIST **ptail,
320  void *data)
321 {
322 DLLIST *cell, *head, *tail;
323 
324  PROCNAME("listAddToTail");
325 
326  if (!phead)
327  return ERROR_INT("&head not defined", procName, 1);
328  head = *phead;
329  if (!ptail)
330  return ERROR_INT("&tail not defined", procName, 1);
331  if (!data)
332  return ERROR_INT("data not defined", procName, 1);
333 
334  if ((cell = (DLLIST *)CALLOC(1, sizeof(DLLIST))) == NULL)
335  return ERROR_INT("cell not made", procName, 1);
336  cell->data = data;
337 
338  if (!head) { /* Start the list and initialize the ptrs. *ptail
339  * should also have been initialized to NULL */
340  cell->prev = NULL;
341  cell->next = NULL;
342  *phead = cell;
343  *ptail = cell;
344  }
345  else {
346  if ((tail = *ptail) == NULL)
348  cell->prev = tail;
349  cell->next = NULL;
350  tail->next = cell;
351  *ptail = cell;
352  }
353 
354  return 0;
355 }
356 
357 
358 /*!
359  * listInsertBefore()
360  *
361  * Input: &head (<optional> input head)
362  * elem (list element to be inserted in front of;
363  * must be null if head is null)
364  * data (void* address, to be added)
365  * Return: 0 if OK; 1 on error
366  *
367  * Usage note:
368  * (1) This can be called on a null list, in which case both
369  * head and elem must be null.
370  * (2) If you are searching through a list, looking for a condition
371  * to add an element, you can do something like this:
372  * L_BEGIN_LIST_FORWARD(head, elem)
373  * <identify an elem to insert before>
374  * listInsertBefore(&head, elem, data);
375  * L_END_LIST
376  *
377  */
378 l_int32
380  DLLIST *elem,
381  void *data)
382 {
383 DLLIST *cell, *head;
384 
385  PROCNAME("listInsertBefore");
386 
387  if (!phead)
388  return ERROR_INT("&head not defined", procName, 1);
389  head = *phead;
390  if (!data)
391  return ERROR_INT("data not defined", procName, 1);
392  if ((!head && elem) || (head && !elem))
393  return ERROR_INT("head and elem not consistent", procName, 1);
394 
395  if ((cell = (DLLIST *)CALLOC(1, sizeof(DLLIST))) == NULL)
396  return ERROR_INT("cell not made", procName, 1);
397  cell->data = data;
398 
399  if (!head) { /* start the list; initialize the ptrs */
400  cell->prev = NULL;
401  cell->next = NULL;
402  *phead = cell;
403  }
404  else if (head == elem) { /* insert before head of list */
405  cell->prev = NULL;
406  cell->next = head;
407  head->prev = cell;
408  *phead = cell;
409  }
410  else { /* insert after head of list */
411  cell->prev = elem->prev;
412  cell->next = elem;
413  elem->prev->next = cell;
414  elem->prev = cell;
415  }
416  return 0;
417 }
418 
419 
420 /*!
421  * listInsertAfter()
422  *
423  * Input: &head (<optional> input head)
424  * elem (list element to be inserted after;
425  * must be null if head is null)
426  * data (void* ptr, to be added)
427  * Return: 0 if OK; 1 on error
428  *
429  * Usage note:
430  * (1) This can be called on a null list, in which case both
431  * head and elem must be null. The head is included
432  * in the call to allow "consing" up from NULL.
433  * (2) If you are searching through a list, looking for a condition
434  * to add an element, you can do something like this:
435  * L_BEGIN_LIST_FORWARD(head, elem)
436  * <identify an elem to insert after>
437  * listInsertAfter(&head, elem, data);
438  * L_END_LIST
439  *
440  */
441 l_int32
443  DLLIST *elem,
444  void *data)
445 {
446 DLLIST *cell, *head;
447 
448  PROCNAME("listInsertAfter");
449 
450  if (!phead)
451  return ERROR_INT("&head not defined", procName, 1);
452  head = *phead;
453  if (!data)
454  return ERROR_INT("data not defined", procName, 1);
455  if ((!head && elem) || (head && !elem))
456  return ERROR_INT("head and elem not consistent", procName, 1);
457 
458  if ((cell = (DLLIST *)CALLOC(1, sizeof(DLLIST))) == NULL)
459  return ERROR_INT("cell not made", procName, 1);
460  cell->data = data;
461 
462  if (!head) { /* start the list; initialize the ptrs */
463  cell->prev = NULL;
464  cell->next = NULL;
465  *phead = cell;
466  }
467  else if (elem->next == NULL) { /* insert after last */
468  cell->prev = elem;
469  cell->next = NULL;
470  elem->next = cell;
471  }
472  else { /* insert within the list elem */
473  cell->prev = elem;
474  cell->next = elem->next;
475  elem->next->prev = cell;
476  elem->next = cell;
477  }
478  return 0;
479 }
480 
481 
482 /*!
483  * listRemoveElement()
484  *
485  * Input: &head (<can be changed> input head)
486  * elem (list element to be removed)
487  * Return: data (void* struct on cell)
488  *
489  * Usage: in ANSI C, it is not necessary to cast return to
490  * actual type; e.g.,
491  * pix = listRemoveElement(&head, elem);
492  * but in ANSI C++, it is necessary to do the cast:
493  * pix = (PIX *)listRemoveElement(&head, elem);
494  */
495 void *
497  DLLIST *elem)
498 {
499 void *data;
500 DLLIST *head;
501 
502  PROCNAME("listRemoveElement");
503 
504  if (!phead)
505  return (void *)ERROR_PTR("&head not defined", procName, NULL);
506  head = *phead;
507  if (!head)
508  return (void *)ERROR_PTR("head not defined", procName, NULL);
509  if (!elem)
510  return (void *)ERROR_PTR("elem not defined", procName, NULL);
511 
512  data = elem->data;
513 
514  if (head->next == NULL) { /* only one */
515  if (elem != head)
516  return (void *)ERROR_PTR("elem must be head", procName, NULL);
517  *phead = NULL;
518  }
519  else if (head == elem) { /* first one */
520  elem->next->prev = NULL;
521  *phead = elem->next;
522  }
523  else if (elem->next == NULL) { /* last one */
524  elem->prev->next = NULL;
525  }
526  else { /* neither the first nor the last one */
527  elem->next->prev = elem->prev;
528  elem->prev->next = elem->next;
529  }
530 
531  FREE((void *)elem);
532  return data;
533 }
534 
535 
536 /*!
537  * listRemoveFromHead()
538  *
539  * Input: &head (<to be updated> head of list)
540  * Return: data (void* struct on cell), or null on error
541  *
542  * Usage: in ANSI C, it is not necessary to cast return to
543  * actual type; e.g.,
544  * pix = listRemoveFromHead(&head);
545  * but in ANSI C++, it is necessary to do the cast; e.g.,
546  * pix = (PIX *)listRemoveFromHead(&head);
547  */
548 void *
550 {
551 DLLIST *head;
552 void *data;
553 
554  PROCNAME("listRemoveFromHead");
555 
556  if (!phead)
557  return (void *)ERROR_PTR("&head not defined", procName, NULL);
558  if ((head = *phead) == NULL)
559  return (void *)ERROR_PTR("head not defined", procName, NULL);
560 
561  if (head->next == NULL) /* only one */
562  *phead = NULL;
563  else {
564  head->next->prev = NULL;
565  *phead = head->next;
566  }
567 
568  data = head->data;
569  FREE((void *)head);
570  return data;
571 }
572 
573 
574 /*!
575  * listRemoveFromTail()
576  *
577  * Input: &head (<may be changed>, head must NOT be null)
578  * &tail (<always updated>, tail may be null)
579  * Return: data (void* struct on cell) or null on error
580  *
581  * Note: we include the &head so that it can be set to NULL
582  * if the only element is removed.
583  *
584  * Usage notes:
585  * (1) The function is relying on the fact that if tail is
586  * not NULL, then is is a valid address. You can use
587  * this function with tail == NULL for an existing list;
588  * the tail is found and updated, and the removed element
589  * is returned.
590  * (2) In ANSI C, it is not necessary to cast return to
591  * actual type; e.g.,
592  * pix = listRemoveFromTail(&head, &tail);
593  * but in ANSI C++, it is necessary to do the cast; e.g.,
594  * pix = (PIX *)listRemoveFromTail(&head, &tail);
595  */
596 void *
598  DLLIST **ptail)
599 {
600 DLLIST *head, *tail;
601 void *data;
602 
603  PROCNAME("listRemoveFromTail");
604 
605  if (!phead)
606  return (void *)ERROR_PTR("&head not defined", procName, NULL);
607  if ((head = *phead) == NULL)
608  return (void *)ERROR_PTR("head not defined", procName, NULL);
609  if (!ptail)
610  return (void *)ERROR_PTR("&tail not defined", procName, NULL);
611  if ((tail = *ptail) == NULL)
613 
614  if (head->next == NULL) { /* only one */
615  *phead = NULL;
616  *ptail = NULL;
617  }
618  else {
619  tail->prev->next = NULL;
620  *ptail = tail->prev;
621  }
622 
623  data = tail->data;
624  FREE((void *)tail);
625  return data;
626 }
627 
628 
629 
630 /*---------------------------------------------------------------------*
631  * Other list operations *
632  *---------------------------------------------------------------------*/
633 /*!
634  * listFindElement()
635  *
636  * Input: head (list head)
637  * data (void* address, to be searched for)
638  * Return: cell (the containing cell, or null if not found or on error)
639  *
640  * Note: this returns a ptr to the cell, which is still
641  * embedded in the list. This handle and the attached
642  * data have not been copied or ref counted, so they
643  * must not be destroyed. This violates our basic rule
644  * that every handle returned from a function is owned
645  * by that function and must be destroyed, but if rules
646  * aren't there to be broken, why have them?
647  *
648  */
649 DLLIST *
651  void *data)
652 {
653 DLLIST *cell;
654 
655  PROCNAME("listFindElement");
656 
657  if (!head)
658  return (DLLIST *)ERROR_PTR("head not defined", procName, NULL);
659  if (!data)
660  return (DLLIST *)ERROR_PTR("data not defined", procName, NULL);
661 
662  for (cell = head; cell; cell = cell->next) {
663  if (cell->data == data)
664  return cell;
665  }
666 
667  return NULL;
668 }
669 
670 
671 /*!
672  * listFindTail()
673  *
674  * Input: head
675  * Return: tail, or null on error
676  */
677 DLLIST *
679 {
680 DLLIST *cell;
681 
682  PROCNAME("listFindTail");
683 
684  if (!head)
685  return (DLLIST *)ERROR_PTR("head not defined", procName, NULL);
686 
687  for (cell = head; cell; cell = cell->next) {
688  if (cell->next == NULL)
689  return cell;
690  }
691 
692  return (DLLIST *)ERROR_PTR("tail not found !!", procName, NULL);
693 }
694 
695 
696 /*!
697  * listGetCount()
698  *
699  * Input: head (of list)
700  * Return: number of elements; 0 if no list or on error
701  *
702  */
703 l_int32
705 {
706 l_int32 count;
707 DLLIST *elem;
708 
709  PROCNAME("listGetCount");
710 
711  if (!head)
712  return ERROR_INT("head not defined", procName, 0);
713 
714  count = 0;
715  for (elem = head; elem; elem = elem->next)
716  count++;
717 
718  return count;
719 }
720 
721 
722 /*!
723  * listReverse()
724  *
725  * Input: &head (<may be changed> list head)
726  * Return: 0 if OK, 1 on error
727  *
728  * Note: this is an in-place function; the list is
729  * just reversed.
730  *
731  */
732 l_int32
734 {
735 void *obj; /* whatever */
736 DLLIST *head, *rhead;
737 
738  PROCNAME("listReverse");
739 
740  if (!phead)
741  return ERROR_INT("&head not defined", procName, 1);
742  if ((head = *phead) == NULL)
743  return ERROR_INT("head not defined", procName, 1);
744 
745  rhead = NULL;
746  while (head) {
747  obj = listRemoveFromHead(&head);
748  listAddToHead(&rhead, obj);
749  }
750 
751  *phead = rhead;
752  return 0;
753 }
754 
755 
756 /*!
757  * listJoin()
758  *
759  * Input: &head1 (<may be changed> head of first list)
760  * &head2 (<to be nulled> head of second list)
761  * Return: 0 if OK, 1 on error
762  *
763  * Usage note:
764  * * The concatenated list is returned with head1 as the new head.
765  * * Both input ptrs must exist, though either can have the
766  * value NULL.
767  *
768  */
769 l_int32
770 listJoin(DLLIST **phead1,
771  DLLIST **phead2)
772 {
773 void *obj;
774 DLLIST *head1, *head2, *tail1;
775 
776  PROCNAME("listJoin");
777 
778  if (!phead1)
779  return ERROR_INT("&head1 not defined", procName, 1);
780  if (!phead2)
781  return ERROR_INT("&head2 not defined", procName, 1);
782 
783  /* if no list2, just return list1 unchanged */
784  if ((head2 = *phead2) == NULL)
785  return 0;
786 
787  /* if no list1, just return list2 */
788  if ((head1 = *phead1) == NULL) {
789  *phead1 = head2;
790  *phead2 = NULL;
791  return 0;
792  }
793 
794  /* general case for concatenation into list 1 */
795  tail1 = listFindTail(head1);
796  while (head2) {
797  obj = listRemoveFromHead(&head2);
798  listAddToTail(&head1, &tail1, obj);
799  }
800  *phead2 = NULL;
801  return 0;
802 }
#define head
Definition: aptex-macros.h:513
#define count(a)
Definition: aptex-macros.h:781
#define next(a)
Definition: aptex-macros.h:924
#define tail
Definition: aptex-macros.h:514
struct rect data
Definition: dvipdfm.c:64
#define PROCNAME(name)
Definition: environ.h:131
#define ERROR_PTR(a, b, c)
Definition: environ.h:132
#define L_WARNING(a, b)
Definition: environ.h:136
#define ERROR_INT(a, b, c)
Definition: environ.h:133
int l_int32
Definition: environ.h:32
const unsigned char FREE
Definition: image.cpp:34
l_int32 listAddToTail(DLLIST **phead, DLLIST **ptail, void *data)
Definition: list.c:318
l_int32 listJoin(DLLIST **phead1, DLLIST **phead2)
Definition: list.c:770
void * listRemoveFromTail(DLLIST **phead, DLLIST **ptail)
Definition: list.c:597
void * listRemoveFromHead(DLLIST **phead)
Definition: list.c:549
void * listRemoveElement(DLLIST **phead, DLLIST *elem)
Definition: list.c:496
DLLIST * listFindTail(DLLIST *head)
Definition: list.c:678
l_int32 listAddToHead(DLLIST **phead, void *data)
Definition: list.c:263
l_int32 listInsertAfter(DLLIST **phead, DLLIST *elem, void *data)
Definition: list.c:442
DLLIST * listFindElement(DLLIST *head, void *data)
Definition: list.c:650
l_int32 listReverse(DLLIST **phead)
Definition: list.c:733
l_int32 listGetCount(DLLIST *head)
Definition: list.c:704
void listDestroy(DLLIST **phead)
Definition: list.c:224
l_int32 listInsertBefore(DLLIST **phead, DLLIST *elem, void *data)
Definition: list.c:379
#define NULL
Definition: ftobjs.h:61
#define CALLOC(t, n)
Definition: hash.c:21
struct cell_struct cell
void * data
Definition: list.h:54
struct DoubleLinkedList * next
Definition: list.h:53
struct DoubleLinkedList * prev
Definition: list.h:52
struct cell * prev
struct cell * next
Definition: ttf.h:354