GRASS GIS 8 Programmer's Manual  8.5.0dev(2024)-602118adcc
vector/Vlib/list.c
Go to the documentation of this file.
1 /*!
2  * \file lib/vector/Vlib/list.c
3  *
4  * \brief Vector library - list definition
5  *
6  * Higher level functions for reading/writing/manipulating vectors.
7  *
8  * (C) 2001-2009 by the GRASS Development Team
9  *
10  * This program is free software under the GNU General Public
11  * License (>=v2). Read the file COPYING that comes with GRASS
12  * for details.
13  *
14  * \author Original author CERL, probably Dave Gerdes or Mike Higgins.
15  * \author Update to GRASS 5.7 Radim Blazek and David D. Gray
16  * \author Update to GRASS 7 Markus Metz
17  */
18 
19 #include <stdlib.h>
20 #include <grass/vector.h>
21 
22 /**
23  * \brief Creates and initializes a struct ilist.
24  *
25  * This structure is used as container for integer values. The
26  * library routines handle all memory allocation.
27  *
28  * \return pointer to struct ilist
29  * \return NULL on error
30  */
31 struct ilist *Vect_new_list(void)
32 {
33  struct ilist *p;
34 
35  p = (struct ilist *)G_malloc(sizeof(struct ilist));
36 
37  if (p) {
38  p->value = NULL;
39  p->n_values = 0;
40  p->alloc_values = 0;
41  }
42 
43  return p;
44 }
45 
46 /**
47  * \brief Reset ilist structure.
48  *
49  * To make sure ilist structure is clean to be re-used. List must have
50  * previously been created with Vect_new_list().
51  *
52  * \param[in,out] list pointer to struct ilist
53  *
54  * \return 0
55  */
57 {
58  list->n_values = 0;
59 
60  return 0;
61 }
62 
63 /**
64  * \brief Frees all memory associated with a struct ilist, including
65  * the struct itself
66  *
67  * \param[in,out] list pointer to ilist structure
68  */
70 {
71  if (list) { /* probably a moot test */
72  if (list->alloc_values) {
73  G_free((void *)list->value);
74  }
75  G_free((void *)list);
76  }
77  list = NULL;
78 }
79 
80 /**
81  * \brief Append new item to the end of list if not yet present
82  *
83  * \param[in,out] list pointer to ilist structure
84  * \param val new item to append to the end of list
85  *
86  * \return 0 on success
87  * \return 1 on error
88  */
89 int Vect_list_append(struct ilist *list, int val)
90 {
91  int i;
92  size_t size;
93 
94  if (list == NULL)
95  return 1;
96 
97  for (i = 0; i < list->n_values; i++) {
98  if (val == list->value[i])
99  return 0;
100  }
101 
102  if (list->n_values == list->alloc_values) {
103  size = (list->n_values + 1000) * sizeof(int);
104  list->value = (int *)G_realloc((void *)list->value, size);
105  list->alloc_values = list->n_values + 1000;
106  }
107 
108  list->value[list->n_values] = val;
109  list->n_values++;
110 
111  return 0;
112 }
113 
114 /**
115  * \brief Append new items to the end of list if not yet present
116  *
117  * \param[in,out] alist pointer to ilist structure where items will be appended
118  * \param blist pointer to ilist structure with new items
119  *
120  * \return 0 on success
121  * \return 1 on error
122  */
123 int Vect_list_append_list(struct ilist *alist, const struct ilist *blist)
124 {
125  int i;
126 
127  if (alist == NULL || blist == NULL)
128  return 1;
129 
130  for (i = 0; i < blist->n_values; i++)
131  Vect_list_append(alist, blist->value[i]);
132 
133  return 0;
134 }
135 
136 /**
137  * \brief Remove a given value (item) from list
138  *
139  * \param[in,out] list pointer to ilist structure
140  * \param val to remove
141  *
142  * \return 0 on success
143  * \return 1 on error
144  */
145 int Vect_list_delete(struct ilist *list, int val)
146 {
147  int i, j;
148 
149  if (list == NULL)
150  return 1;
151 
152  for (i = 0; i < list->n_values; i++) {
153  if (val == list->value[i]) {
154  for (j = i + 1; j < list->n_values; j++)
155  list->value[j - 1] = list->value[j];
156 
157  list->n_values--;
158  return 0;
159  }
160  }
161 
162  return 0;
163 }
164 
165 /**
166  * \brief Delete list from existing list
167  *
168  * \param[in,out] alist pointer to original ilist structure,
169  * \param blist pointer to ilist structure with items to delete
170  *
171  * \return 0 on success
172  * \return 1 on error
173  */
174 int Vect_list_delete_list(struct ilist *alist, const struct ilist *blist)
175 {
176  int i;
177 
178  if (alist == NULL || blist == NULL)
179  return 1;
180 
181  for (i = 0; i < blist->n_values; i++)
182  Vect_list_delete(alist, blist->value[i]);
183 
184  return 0;
185 }
186 
187 /**
188  * \brief Find a given item in the list
189  *
190  * \param list pointer to ilist structure
191  * \param val value of item
192  *
193  * \return 1 if an item is found
194  * \return 0 no found item in the list
195  */
196 int Vect_val_in_list(const struct ilist *list, int val)
197 {
198  int i;
199 
200  if (list == NULL)
201  return 0;
202 
203  for (i = 0; i < list->n_values; i++) {
204  if (val == list->value[i])
205  return 1;
206  }
207 
208  return 0;
209 }
210 
211 /* box list routines */
212 
213 /**
214  * \brief Creates and initializes a struct boxlist.
215  *
216  * This structure is used as container for bounding boxes with id. The
217  * library routines handle all memory allocation.
218  *
219  * \param have_boxes if set to 0, the list will hold only ids and no boxes
220  *
221  * \return pointer to struct boxlist
222  * \return NULL on error
223  */
225 {
226  struct boxlist *p;
227 
228  p = (struct boxlist *)G_malloc(sizeof(struct boxlist));
229 
230  if (p) {
231  p->id = NULL;
232  p->box = NULL;
233  p->have_boxes = have_boxes != 0;
234  p->n_values = 0;
235  p->alloc_values = 0;
236  }
237 
238  return p;
239 }
240 
241 /**
242  * \brief Reset boxlist structure.
243  *
244  * To make sure boxlist structure is clean to be re-used. List must have
245  * previously been created with Vect_new_boxlist().
246  *
247  * \param[in,out] list pointer to struct boxlist
248  *
249  * \return 0
250  */
252 {
253  list->n_values = 0;
254 
255  return 0;
256 }
257 
258 /**
259  * \brief Frees all memory associated with a struct boxlist, including
260  * the struct itself
261  *
262  * \param[in,out] list pointer to ilist structure
263  */
265 {
266  if (list) { /* probably a moot test */
267  if (list->alloc_values) {
268  G_free((void *)list->id);
269  if (list->box)
270  G_free((void *)list->box);
271  }
272  G_free((void *)list);
273  }
274  list = NULL;
275 }
276 
277 /**
278  * \brief Append new item to the end of list if not yet present
279  *
280  * \param[in,out] list pointer to ilist structure
281  * \param id new item to append to the end of list
282  * \param box bounding box
283  *
284  * \return 0 on success
285  * \return 1 on error
286  */
287 int Vect_boxlist_append(struct boxlist *list, int id,
288  const struct bound_box *box)
289 {
290  int i;
291  size_t size;
292 
293  if (list == NULL)
294  return 1;
295 
296  for (i = 0; i < list->n_values; i++) {
297  if (id == list->id[i])
298  return 0;
299  }
300 
301  if (list->n_values == list->alloc_values) {
302  size = (list->n_values + 1000) * sizeof(int);
303  list->id = (int *)G_realloc((void *)list->id, size);
304 
305  if (list->have_boxes) {
306  size = (list->n_values + 1000) * sizeof(struct bound_box);
307  list->box = (struct bound_box *)G_realloc((void *)list->box, size);
308  }
309 
310  list->alloc_values = list->n_values + 1000;
311  }
312 
313  list->id[list->n_values] = id;
314  if (list->have_boxes)
315  list->box[list->n_values] = *box;
316  list->n_values++;
317 
318  return 0;
319 }
320 
321 /**
322  * \brief Append new items to the end of list if not yet present
323  *
324  * \param[in,out] alist pointer to boxlist structure where items will be
325  * appended \param blist pointer to boxlist structure with new items
326  *
327  * \return 0 on success
328  * \return 1 on error
329  */
331  const struct boxlist *blist)
332 {
333  int i;
334 
335  if (alist == NULL || blist == NULL)
336  return 1;
337 
338  if (blist->have_boxes) {
339  for (i = 0; i < blist->n_values; i++)
340  Vect_boxlist_append(alist, blist->id[i], &blist->box[i]);
341  }
342  else {
343  struct bound_box box;
344 
345  box.E = box.W = box.N = box.S = box.T = box.B = 0;
346  for (i = 0; i < blist->n_values; i++)
347  Vect_boxlist_append(alist, blist->id[i], &box);
348  }
349 
350  return 0;
351 }
352 
353 /**
354  * \brief Remove a given value (item) from list
355  *
356  * \param[in,out] list pointer to boxlist structure
357  * \param id to remove
358  *
359  * \return 0 on success
360  * \return 1 on error
361  */
362 int Vect_boxlist_delete(struct boxlist *list, int id)
363 {
364  int i, j;
365 
366  if (list == NULL)
367  return 1;
368 
369  for (i = 0; i < list->n_values; i++) {
370  if (id == list->id[i]) {
371  for (j = i + 1; j < list->n_values; j++) {
372  list->id[j - 1] = list->id[j];
373  if (list->have_boxes)
374  list->box[j - 1] = list->box[j];
375  }
376 
377  list->n_values--;
378  return 0;
379  }
380  }
381 
382  return 0;
383 }
384 
385 /**
386  * \brief Delete list from existing list
387  *
388  * \param[in,out] alist pointer to original boxlist structure,
389  * \param blist pointer to boxlist structure with items to delete
390  *
391  * \return 0 on success
392  * \return 1 on error
393  */
395  const struct boxlist *blist)
396 {
397  int i;
398 
399  if (alist == NULL || blist == NULL)
400  return 1;
401 
402  for (i = 0; i < blist->n_values; i++)
403  Vect_boxlist_delete(alist, blist->id[i]);
404 
405  return 0;
406 }
407 
408 /**
409  * \brief Find a given item in the list
410  *
411  * \param list pointer to boxlist structure
412  * \param id value of item
413  *
414  * \return 1 if an item is found
415  * \return 0 no found item in the list
416  */
417 int Vect_val_in_boxlist(const struct boxlist *list, int id)
418 {
419  int i;
420 
421  if (list == NULL)
422  return 0;
423 
424  for (i = 0; i < list->n_values; i++) {
425  if (id == list->id[i])
426  return 1;
427  }
428 
429  return 0;
430 }
#define NULL
Definition: ccmath.h:32
void G_free(void *)
Free allocated memory.
Definition: gis/alloc.c:150
#define G_realloc(p, n)
Definition: defs/gis.h:96
#define G_malloc(n)
Definition: defs/gis.h:94
Bounding box.
Definition: dig_structs.h:64
double W
West.
Definition: dig_structs.h:80
double T
Top.
Definition: dig_structs.h:84
double S
South.
Definition: dig_structs.h:72
double N
North.
Definition: dig_structs.h:68
double E
East.
Definition: dig_structs.h:76
double B
Bottom.
Definition: dig_structs.h:88
List of bounding boxes with id.
Definition: dig_structs.h:1723
int alloc_values
Allocated space for items.
Definition: dig_structs.h:1743
int * id
Array of ids.
Definition: dig_structs.h:1727
struct bound_box * box
Array of bounding boxes.
Definition: dig_structs.h:1731
int n_values
Number of items in the list.
Definition: dig_structs.h:1739
int have_boxes
flag to indicate whether bounding boxes should be added
Definition: dig_structs.h:1735
List of integers.
Definition: gis.h:709
int n_values
Number of values in the list.
Definition: gis.h:717
int * value
Array of values.
Definition: gis.h:713
int alloc_values
Allocated space for values.
Definition: gis.h:721
Definition: manage.h:4
void Vect_destroy_list(struct ilist *list)
Frees all memory associated with a struct ilist, including the struct itself.
int Vect_reset_list(struct ilist *list)
Reset ilist structure.
int Vect_val_in_list(const struct ilist *list, int val)
Find a given item in the list.
int Vect_boxlist_delete(struct boxlist *list, int id)
Remove a given value (item) from list.
struct boxlist * Vect_new_boxlist(int have_boxes)
Creates and initializes a struct boxlist.
int Vect_list_delete(struct ilist *list, int val)
Remove a given value (item) from list.
int Vect_list_append_list(struct ilist *alist, const struct ilist *blist)
Append new items to the end of list if not yet present.
void Vect_destroy_boxlist(struct boxlist *list)
Frees all memory associated with a struct boxlist, including the struct itself.
struct ilist * Vect_new_list(void)
Creates and initializes a struct ilist.
int Vect_val_in_boxlist(const struct boxlist *list, int id)
Find a given item in the list.
int Vect_boxlist_append(struct boxlist *list, int id, const struct bound_box *box)
Append new item to the end of list if not yet present.
int Vect_list_delete_list(struct ilist *alist, const struct ilist *blist)
Delete list from existing list.
int Vect_reset_boxlist(struct boxlist *list)
Reset boxlist structure.
int Vect_boxlist_append_boxlist(struct boxlist *alist, const struct boxlist *blist)
Append new items to the end of list if not yet present.
int Vect_boxlist_delete_boxlist(struct boxlist *alist, const struct boxlist *blist)
Delete list from existing list.
int Vect_list_append(struct ilist *list, int val)
Append new item to the end of list if not yet present.