Coverage Report

Created: 2026-09-14 06:59

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