tesseract  4.1.0
oldlist.cpp
Go to the documentation of this file.
1 /* -*-C-*-
2 ###############################################################################
3 #
4 # File: oldlist.cpp
5 # Description: List processing procedures.
6 # Author: Mark Seaman, Software Productivity
7 #
8 # (c) Copyright 1987, Hewlett-Packard Company.
9 ** Licensed under the Apache License, Version 2.0 (the "License");
10 ** you may not use this file except in compliance with the License.
11 ** You may obtain a copy of the License at
12 ** http://www.apache.org/licenses/LICENSE-2.0
13 ** Unless required by applicable law or agreed to in writing, software
14 ** distributed under the License is distributed on an "AS IS" BASIS,
15 ** WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 ** See the License for the specific language governing permissions and
17 ** limitations under the License.
18 #
19 ###############################################################################
20 
21  This file contains a set of general purpose list manipulation routines.
22  These routines can be used in a wide variety of ways to provide several
23  different popular data structures. A new list can be created by declaring
24  a variable of type 'LIST', and can be initialized with the value 'NIL_LIST'.
25  All of these routines check for the NIL_LIST condition before dereferencing
26  pointers. NOTE: There is a users' manual available in printed form from
27  Mark Seaman at (303) 350-4492 at Greeley Hard Copy.
28 
29  To implement a STACK use:
30 
31  push to add to the Stack l = push(l, (LIST)"jim");
32  pop to remove items from the Stack l = pop(l);
33  first_node to access the head name = (char *)first_node(l);
34 
35  To implement a QUEUE use:
36 
37  push_last to add to the Queue l = push_last(l, (LIST)"x");
38  pop remove items from the Queue l = pop(l);
39  first_node to access the head name = (char *)first_node (l);
40 
41  To implement LISP like functions use:
42 
43  first_node CAR x = (int)first_node(l);
44  rest CDR l = list_rest (l);
45  push CONS l = push(l, (LIST)this);
46  last LAST x = last(l);
47  concat APPEND l = concat(r, s);
48  count LENGTH x = count(l);
49  search MEMBER if (search(l, x, nullptr))
50 
51  The following rules of closure exist for the functions provided.
52  a = first_node (push (a, b))
53  b = list_rest (push (a, b))
54  a = push (pop (a), a)) For all a <> NIL_LIST
55  a = reverse (reverse (a))
56 
57 ******************************************************************************/
58 #include "oldlist.h"
59 #include <cstdio>
60 #include <cstring> // for strcmp
61 #include "errcode.h" // for ASSERT_HOST
62 #include "structures.h"
63 
64 /**********************************************************************
65  * c o p y f i r s t
66  *
67  * Do the appropriate kind a push operation to copy the first node from
68  * one list to another.
69  *
70  **********************************************************************/
71 
72 #define copy_first(l1,l2) \
73 (l2=push(l2, first_node(l1)))
74 
75 
76 
77 /*----------------------------------------------------------------------
78  F u n c t i o n s
79 ----------------------------------------------------------------------*/
80 
81 /**********************************************************************
82  * i s s a m e
83  *
84  * Compare the list node with the key value return true (non-zero)
85  * if they are equivalent strings. (Return false if not)
86  **********************************************************************/
87 static int is_same(void *item1, void *item2) {
88  return strcmp(static_cast<char *>(item1), static_cast<char *>(item2)) == 0;
89 }
90 
91 /**********************************************************************
92  * c o u n t
93  *
94  * Recursively count the elements in a list. Return the count.
95  **********************************************************************/
96 int count(LIST var_list) {
97  int temp = 0;
98 
99  iterate(var_list) temp += 1;
100  return (temp);
101 }
102 
103 /**********************************************************************
104  * d e l e t e d
105  *
106  * Delete all the elements out of the current list that match the key.
107  * This operation destroys the original list. The caller will supply a
108  * routine that will compare each node to the
109  * key, and return a non-zero value when they match.
110  **********************************************************************/
111 LIST delete_d(LIST list, void *key, int_compare is_equal) {
112  LIST result = NIL_LIST;
113  LIST last_one = NIL_LIST;
114 
115  if (is_equal == nullptr) is_equal = is_same;
116 
117  while (list != NIL_LIST) {
118  if (!(*is_equal)(first_node(list), key)) {
119  if (last_one == NIL_LIST) {
120  last_one = list;
121  list = list_rest(list);
122  result = last_one;
123  set_rest(last_one, NIL_LIST);
124  } else {
125  set_rest(last_one, list);
126  last_one = list;
127  list = list_rest(list);
128  set_rest(last_one, NIL_LIST);
129  }
130  } else {
131  list = pop(list);
132  }
133  }
134  return (result);
135 }
136 
137 /**********************************************************************
138  * d e s t r o y
139  *
140  * Return the space taken by a list to the heap.
141  **********************************************************************/
143  LIST next;
144 
145  while (list != NIL_LIST) {
146  next = list_rest(list);
147  free_cell(list);
148  list = next;
149  }
150  return (NIL_LIST);
151 }
152 
153 /**********************************************************************
154  * d e s t r o y n o d e s
155  *
156  * Return the space taken by the LISTs of a list to the heap.
157  **********************************************************************/
158 void destroy_nodes(LIST list, void_dest destructor) {
159  ASSERT_HOST(destructor != nullptr);
160 
161  while (list != NIL_LIST) {
162  if (first_node(list) != nullptr) (*destructor)(first_node(list));
163  list = pop(list);
164  }
165 }
166 
167 /**********************************************************************
168  * i n s e r t
169  *
170  * Create a list element and rearrange the pointers so that the first
171  * element in the list is the second argument.
172  **********************************************************************/
173 void insert(LIST list, void *node) {
174  LIST element;
175 
176  if (list != NIL_LIST) {
177  element = push(NIL_LIST, node);
178  set_rest(element, list_rest(list));
179  set_rest(list, element);
180  node = first_node(list);
181  list->node = first_node(list_rest(list));
182  list->next->node = (LIST)node;
183  }
184 }
185 
186 /**********************************************************************
187  * l a s t
188  *
189  * Return the last list item (this is list type).
190  **********************************************************************/
191 LIST last(LIST var_list) {
192  while (list_rest(var_list) != NIL_LIST) var_list = list_rest(var_list);
193  return (var_list);
194 }
195 
196 /**********************************************************************
197  * p o p
198  *
199  * Return the list with the first element removed. Destroy the space
200  * that it occupied in the list.
201  **********************************************************************/
202 LIST pop(LIST list) {
203  LIST temp;
204 
205  temp = list_rest(list);
206 
207  if (list != NIL_LIST) {
208  free_cell(list);
209  }
210  return (temp);
211 }
212 
213 /**********************************************************************
214  * p u s h
215  *
216  * Create a list element. Push the second parameter (the node) onto
217  * the first parameter (the list). Return the new list to the caller.
218  **********************************************************************/
219 LIST push(LIST list, void *element) {
220  LIST t;
221 
222  t = new_cell();
223  t->node = static_cast<LIST>(element);
224  set_rest(t, list);
225  return (t);
226 }
227 
228 /**********************************************************************
229  * p u s h l a s t
230  *
231  * Create a list element. Add the element onto the end of the list.
232  **********************************************************************/
233 LIST push_last(LIST list, void *item) {
234  LIST t;
235 
236  if (list != NIL_LIST) {
237  t = last(list);
238  t->next = push(NIL_LIST, item);
239  return (list);
240  } else
241  return (push(NIL_LIST, item));
242 }
243 
244 /**********************************************************************
245  * r e v e r s e
246  *
247  * Create a new list with the elements reversed. The old list is not
248  * destroyed.
249  **********************************************************************/
251  LIST newlist = NIL_LIST;
252 
253  iterate(list) copy_first(list, newlist);
254  return (newlist);
255 }
256 
257 /**********************************************************************
258  * s e a r c h
259  *
260  * Search list, return NIL_LIST if not found. Return the list starting from
261  * the item if found. The compare routine "is_equal" is passed in as
262  * the third parameter to this routine.
263  **********************************************************************/
264 LIST search(LIST list, void *key, int_compare is_equal) {
265  if (is_equal == nullptr) is_equal = is_same;
266 
267  iterate(list) if ((*is_equal)(first_node(list), key)) return (list);
268  return (NIL_LIST);
269 }
LIST last(LIST var_list)
Definition: oldlist.cpp:191
#define set_rest(l, cell)
Definition: oldlist.h:120
LIST new_cell()
LIST push_last(LIST list, void *item)
Definition: oldlist.cpp:233
list_rec * LIST
Definition: oldlist.h:85
LIST push(LIST list, void *element)
Definition: oldlist.cpp:219
LIST search(LIST list, void *key, int_compare is_equal)
Definition: oldlist.cpp:264
#define is_equal(p1, p2)
Definition: outlines.h:105
#define list_rest(l)
Definition: oldlist.h:91
#define NIL_LIST
Definition: oldlist.h:76
#define copy_first(l1, l2)
Definition: oldlist.cpp:72
struct list_rec * node
Definition: oldlist.h:82
void(*)(void *) void_dest
Definition: oldlist.h:79
int(*)(void *, void *) int_compare
Definition: oldlist.h:78
#define first_node(l)
Definition: oldlist.h:92
#define ASSERT_HOST(x)
Definition: errcode.h:88
LIST destroy(LIST list)
Definition: oldlist.cpp:142
void free_cell(LIST)
void insert(LIST list, void *node)
Definition: oldlist.cpp:173
struct list_rec * next
Definition: oldlist.h:83
LIST reverse(LIST list)
Definition: oldlist.cpp:250
LIST delete_d(LIST list, void *key, int_compare is_equal)
Definition: oldlist.cpp:111
void destroy_nodes(LIST list, void_dest destructor)
Definition: oldlist.cpp:158
int count(LIST var_list)
Definition: oldlist.cpp:96
LIST pop(LIST list)
Definition: oldlist.cpp:202
#define iterate(l)
Definition: oldlist.h:101