tesseract  4.00.00dev
oldlist.cpp
Go to the documentation of this file.
1 /* -*-C-*-
2 ###############################################################################
3 #
4 # File: list.c
5 # Description: List processing procedures.
6 # Author: Mark Seaman, Software Productivity
7 # Created: Thu Jul 23 13:24:09 1987
8 # Modified: Thu Dec 22 10:59:52 1988 (Mark Seaman) marks@hpgrlt
9 # Language: C
10 # Package: N/A
11 # Status: Reusable Software Component
12 #
13 # (c) Copyright 1987, Hewlett-Packard Company.
14 ** Licensed under the Apache License, Version 2.0 (the "License");
15 ** you may not use this file except in compliance with the License.
16 ** You may obtain a copy of the License at
17 ** http://www.apache.org/licenses/LICENSE-2.0
18 ** Unless required by applicable law or agreed to in writing, software
19 ** distributed under the License is distributed on an "AS IS" BASIS,
20 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
21 ** See the License for the specific language governing permissions and
22 ** limitations under the License.
23 #
24 ################################################################################
25 
26 * Revision 1.13 90/03/06 15:37:54 15:37:54 marks (Mark Seaman)
27 * Look for correct file of <malloc.h> or <stdlib.h>
28 *
29 * Revision 1.12 90/02/26 17:37:36 17:37:36 marks (Mark Seaman)
30 * Added pop_off and join_on
31 *
32 
33  This file contains a set of general purpose list manipulation routines.
34  These routines can be used in a wide variety of ways to provide several
35  different popular data structures. A new list can be created by declaring
36  a variable of type 'LIST', and can be initialized with the value 'NIL_LIST'.
37  All of these routines check for the NIL_LIST condition before dereferencing
38  pointers. NOTE: There is a users' manual available in printed form from
39  Mark Seaman at (303) 350-4492 at Greeley Hard Copy.
40 
41  To implement a STACK use:
42 
43  push to add to the Stack l = push (l, (LIST) "jim");
44  pop to remove items from the Stack l = pop (l);
45  first_node to access the head name = (char *) first_node (l);
46 
47  To implement a QUEUE use:
48 
49  push_last to add to the Queue l = push_last (l, (LIST) "jim");
50  pop remove items from the Queue l = pop (l);
51  first_node to access the head name = (char *) first_node (l);
52 
53  To implement LISP like functions use:
54 
55  first_node CAR x = (int) first_node (l);
56  rest CDR l = list_rest (l);
57  push CONS l = push (l, (LIST) this);
58  last LAST x = last (l);
59  concat APPEND l = concat (r, s);
60  count LENGTH x = count (l);
61  search MEMBER if (search (l, x, NULL))
62 
63  To implement SETS use:
64 
65  adjoin l = adjoin (l, x);
66  set_union l = set_union (r, s);
67  intersection l = intersection (r, s);
68  set_difference l = set_difference (r, s);
69  delete l = delete (s, x, NULL);
70  search if (search (l, x, NULL))
71 
72  To Implement Associated LISTS use:
73 
74  lpush l = lpush (l, p);
75  assoc s = assoc (l, x);
76  adelete l = adelete (l, x);
77 
78  The following rules of closure exist for the functions provided.
79  a = first_node (push (a, b))
80  b = list_rest (push (a, b))
81  a = push (pop (a), a)) For all a <> NIL_LIST
82  a = reverse (reverse (a))
83 
84 ******************************************************************************/
85 #include "oldlist.h"
86 #include "structures.h"
87 #include <stdio.h>
88 
89 /*----------------------------------------------------------------------
90  M a c r o s
91 ----------------------------------------------------------------------*/
92 #define add_on(l,x) l = push (l,first_node (x))
93 #define next_one(l) l = list_rest (l)
94 
95 /*----------------------------------------------------------------------
96  F u n c t i o n s
97 ----------------------------------------------------------------------*/
98 /**********************************************************************
99  * c o u n t
100  *
101  * Recursively count the elements in a list. Return the count.
102  **********************************************************************/
103 int count(LIST var_list) {
104  int temp = 0;
105 
106  iterate (var_list) temp += 1;
107  return (temp);
108 }
109 
110 
111 /**********************************************************************
112  * d e l e t e d
113  *
114  * Delete all the elements out of the current list that match the key.
115  * This operation destroys the original list. The caller will supply a
116  * routine that will compare each node to the
117  * key, and return a non-zero value when they match. If the value
118  * NULL is supplied for is_equal, the is_key routine will be used.
119  **********************************************************************/
120 LIST delete_d(LIST list, void *key, int_compare is_equal) {
121  LIST result = NIL_LIST;
122  LIST last_one = NIL_LIST;
123 
124  if (is_equal == NULL)
125  is_equal = is_same;
126 
127  while (list != NIL_LIST) {
128  if (!(*is_equal) (first_node (list), key)) {
129  if (last_one == NIL_LIST) {
130  last_one = list;
131  list = list_rest (list);
132  result = last_one;
133  set_rest(last_one, NIL_LIST);
134  }
135  else {
136  set_rest(last_one, list);
137  last_one = list;
138  list = list_rest (list);
139  set_rest(last_one, NIL_LIST);
140  }
141  }
142  else {
143  list = pop (list);
144  }
145  }
146  return (result);
147 }
148 
149 LIST delete_d(LIST list, void *key,
151  LIST result = NIL_LIST;
152  LIST last_one = NIL_LIST;
153 
154  while (list != NIL_LIST) {
155  if (!(*is_equal).Run (first_node (list), key)) {
156  if (last_one == NIL_LIST) {
157  last_one = list;
158  list = list_rest (list);
159  result = last_one;
160  set_rest(last_one, NIL_LIST);
161  }
162  else {
163  set_rest(last_one, list);
164  last_one = list;
165  list = list_rest (list);
166  set_rest(last_one, NIL_LIST);
167  }
168  }
169  else {
170  list = pop (list);
171  }
172  }
173  return (result);
174 }
175 
176 
177 /**********************************************************************
178  * d e s t r o y
179  *
180  * Return the space taken by a list to the heap.
181  **********************************************************************/
183  LIST next;
184 
185  while (list != NIL_LIST) {
186  next = list_rest (list);
187  free_cell(list);
188  list = next;
189  }
190  return (NIL_LIST);
191 }
192 
193 
194 /**********************************************************************
195  * d e s t r o y n o d e s
196  *
197  * Return the space taken by the LISTs of a list to the heap.
198  **********************************************************************/
199 void destroy_nodes(LIST list, void_dest destructor) {
200  ASSERT_HOST(destructor != NULL);
201 
202  while (list != NIL_LIST) {
203  if (first_node(list) != NULL) (*destructor)(first_node(list));
204  list = pop(list);
205  }
206 }
207 
208 
209 /**********************************************************************
210  * i n s e r t
211  *
212  * Create a list element and rearange the pointers so that the first
213  * element in the list is the second aurgment.
214  **********************************************************************/
215 void insert(LIST list, void *node) {
216  LIST element;
217 
218  if (list != NIL_LIST) {
219  element = push (NIL_LIST, node);
220  set_rest (element, list_rest (list));
221  set_rest(list, element);
222  node = first_node (list);
223  list->node = first_node (list_rest (list));
224  list->next->node = (LIST) node;
225  }
226 }
227 
228 
229 /**********************************************************************
230  * i s s a m e n o d e
231  *
232  * Compare the list node with the key value return TRUE (non-zero)
233  * if they are equivalent strings. (Return FALSE if not)
234  **********************************************************************/
235 int is_same_node(void *item1, void *item2) {
236  return (item1 == item2);
237 }
238 
239 
240 /**********************************************************************
241  * i s s a m e
242  *
243  * Compare the list node with the key value return TRUE (non-zero)
244  * if they are equivalent strings. (Return FALSE if not)
245  **********************************************************************/
246 int is_same(void *item1, void *item2) {
247  return (!strcmp ((char *) item1, (char *) item2));
248 }
249 
250 
251 /**********************************************************************
252  * j o i n
253  *
254  * Join the two lists together. This function is similar to concat
255  * except that concat creates a new list. This function returns the
256  * first list updated.
257  **********************************************************************/
258 LIST join(LIST list1, LIST list2) {
259  if (list1 == NIL_LIST)
260  return (list2);
261  set_rest (last (list1), list2);
262  return (list1);
263 }
264 
265 
266 /**********************************************************************
267  * l a s t
268  *
269  * Return the last list item (this is list type).
270  **********************************************************************/
271 LIST last(LIST var_list) {
272  while (list_rest (var_list) != NIL_LIST)
273  var_list = list_rest (var_list);
274  return (var_list);
275 }
276 
277 
278 /**********************************************************************
279  * n t h c e l l
280  *
281  * Return nth list cell in the list.
282  **********************************************************************/
283 void *nth_cell(LIST var_list, int item_num) {
284  int x = 0;
285  iterate(var_list) {
286  if (x++ == item_num)
287  return (var_list);
288  }
289  return (var_list);
290 }
291 
292 
293 /**********************************************************************
294  * p o p
295  *
296  * Return the list with the first element removed. Destroy the space
297  * that it occupied in the list.
298  **********************************************************************/
299 LIST pop(LIST list) {
300  LIST temp;
301 
302  temp = list_rest (list);
303 
304  if (list != NIL_LIST) {
305  free_cell(list);
306  }
307  return (temp);
308 }
309 
310 
311 /**********************************************************************
312  * p u s h
313  *
314  * Create a list element. Push the second parameter (the node) onto
315  * the first parameter (the list). Return the new list to the caller.
316  **********************************************************************/
317 LIST push(LIST list, void *element) {
318  LIST t;
319 
320  t = new_cell ();
321  t->node = (LIST) element;
322  set_rest(t, list);
323  return (t);
324 }
325 
326 
327 /**********************************************************************
328  * p u s h l a s t
329  *
330  * Create a list element. Add the element onto the end of the list.
331  **********************************************************************/
332 LIST push_last(LIST list, void *item) {
333  LIST t;
334 
335  if (list != NIL_LIST) {
336  t = last (list);
337  t->next = push (NIL_LIST, item);
338  return (list);
339  }
340  else
341  return (push (NIL_LIST, item));
342 }
343 
344 
345 /**********************************************************************
346  * r e v e r s e
347  *
348  * Create a new list with the elements reversed. The old list is not
349  * destroyed.
350  **********************************************************************/
352  LIST newlist = NIL_LIST;
353 
354  iterate (list) copy_first (list, newlist);
355  return (newlist);
356 }
357 
358 
359 /**********************************************************************
360  * r e v e r s e d
361  *
362  * Create a new list with the elements reversed. The old list is
363  * destroyed.
364  **********************************************************************/
366  LIST result = reverse (list);
367  destroy(list);
368  return (result);
369 }
370 
371 
372 /**********************************************************************
373  * s a d j o i n
374  *
375  * Adjoin an element to an assorted list. The original list is
376  * modified. Returns the modified list.
377  **********************************************************************/
378 LIST s_adjoin(LIST var_list, void *variable, int_compare compare) {
379  LIST l;
380  int result;
381 
382  if (compare == NULL)
383  compare = (int_compare) strcmp;
384 
385  l = var_list;
386  iterate(l) {
387  result = (*compare) (variable, first_node (l));
388  if (result == 0)
389  return (var_list);
390  else if (result < 0) {
391  insert(l, variable);
392  return (var_list);
393  }
394  }
395  return (push_last (var_list, variable));
396 }
397 
398 /**********************************************************************
399  * s e a r c h
400  *
401  * Search list, return NIL_LIST if not found. Return the list starting from
402  * the item if found. The compare routine "is_equal" is passed in as
403  * the third parameter to this routine. If the value NULL is supplied
404  * for is_equal, the is_key routine will be used.
405  **********************************************************************/
406 LIST search(LIST list, void *key, int_compare is_equal) {
407  if (is_equal == NULL)
408  is_equal = is_same;
409 
410  iterate (list) if ((*is_equal) (first_node (list), key))
411  return (list);
412  return (NIL_LIST);
413 }
414 
416  iterate (list) if ((*is_equal).Run(first_node (list), key))
417  return (list);
418  return (NIL_LIST);
419 }
int is_same_node(void *item1, void *item2)
Definition: oldlist.cpp:235
struct list_rec * node
Definition: oldlist.h:129
LIST destroy(LIST list)
Definition: oldlist.cpp:182
list_rec * LIST
Definition: oldlist.h:132
int is_same(void *item1, void *item2)
Definition: oldlist.cpp:246
void free_cell(LIST)
LIST reverse(LIST list)
Definition: oldlist.cpp:351
void * nth_cell(LIST var_list, int item_num)
Definition: oldlist.cpp:283
LIST push_last(LIST list, void *item)
Definition: oldlist.cpp:332
LIST s_adjoin(LIST var_list, void *variable, int_compare compare)
Definition: oldlist.cpp:378
#define NIL_LIST
Definition: oldlist.h:126
LIST pop(LIST list)
Definition: oldlist.cpp:299
#define ASSERT_HOST(x)
Definition: errcode.h:84
LIST search(LIST list, void *key, int_compare is_equal)
Definition: oldlist.cpp:406
LIST delete_d(LIST list, void *key, int_compare is_equal)
Definition: oldlist.cpp:120
void(* void_dest)(void *)
Definition: cutil.h:72
#define set_rest(l, cell)
Definition: oldlist.h:222
#define first_node(l)
Definition: oldlist.h:139
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:199
#define copy_first(l1, l2)
Definition: oldlist.h:149
#define is_equal(p1, p2)
Definition: outlines.h:109
LIST new_cell()
void insert(LIST list, void *node)
Definition: oldlist.cpp:215
struct list_rec * next
Definition: oldlist.h:130
LIST join(LIST list1, LIST list2)
Definition: oldlist.cpp:258
LIST last(LIST var_list)
Definition: oldlist.cpp:271
#define iterate(l)
Definition: oldlist.h:159
LIST push(LIST list, void *element)
Definition: oldlist.cpp:317
int count(LIST var_list)
Definition: oldlist.cpp:103
LIST reverse_d(LIST list)
Definition: oldlist.cpp:365
#define list_rest(l)
Definition: oldlist.h:138
int(* int_compare)(void *, void *)
Definition: cutil.h:71