]> git.ipfire.org Git - thirdparty/binutils-gdb.git/blame - gdb/gdbsupport/vec.c
gdb: Remove use of VEC from dwarf2read.c
[thirdparty/binutils-gdb.git] / gdb / gdbsupport / vec.c
CommitLineData
350da6ee 1/* Vector API for GDB.
42a4f53d 2 Copyright (C) 2004-2019 Free Software Foundation, Inc.
350da6ee
DJ
3 Contributed by Nathan Sidwell <nathan@codesourcery.com>
4
5 This file is part of GDB.
6
7 This program is free software; you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
a9762ec7 9 the Free Software Foundation; either version 3 of the License, or
350da6ee
DJ
10 (at your option) any later version.
11
12 This program is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
a9762ec7 18 along with this program. If not, see <http://www.gnu.org/licenses/>. */
350da6ee 19
727605ca 20#include "common-defs.h"
8aceae7e 21#include "vec.h"
350da6ee
DJ
22
23struct vec_prefix
24{
25 unsigned num;
26 unsigned alloc;
27 void *vec[1];
28};
29
30/* Calculate the new ALLOC value, making sure that abs(RESERVE) slots
31 are free. If RESERVE < 0 grow exactly, otherwise grow
32 exponentially. */
33
34static inline unsigned
35calculate_allocation (const struct vec_prefix *pfx, int reserve)
36{
37 unsigned alloc = 0;
38 unsigned num = 0;
39
40 if (pfx)
41 {
42 alloc = pfx->alloc;
43 num = pfx->num;
44 }
45 else if (!reserve)
46 /* If there's no prefix, and we've not requested anything, then we
47 will create a NULL vector. */
48 return 0;
49
50 /* We must have run out of room. */
51 gdb_assert (alloc - num < (unsigned)(reserve < 0 ? -reserve : reserve));
52
53 if (reserve < 0)
54 /* Exact size. */
55 alloc = num + -reserve;
56 else
57 {
581e13c1 58 /* Exponential growth. */
350da6ee
DJ
59 if (!alloc)
60 alloc = 4;
61 else if (alloc < 16)
62 /* Double when small. */
63 alloc = alloc * 2;
64 else
65 /* Grow slower when large. */
66 alloc = (alloc * 3 / 2);
67
581e13c1 68 /* If this is still too small, set it to the right size. */
350da6ee
DJ
69 if (alloc < num + reserve)
70 alloc = num + reserve;
71 }
72 return alloc;
73}
74
75/* Ensure there are at least abs(RESERVE) free slots in VEC. If
76 RESERVE < 0 grow exactly, else grow exponentially. As a special
581e13c1 77 case, if VEC is NULL, and RESERVE is 0, no vector will be created. */
350da6ee
DJ
78
79void *
80vec_p_reserve (void *vec, int reserve)
81{
82 return vec_o_reserve (vec, reserve,
83 offsetof (struct vec_prefix, vec), sizeof (void *));
84}
85
86/* As vec_p_reserve, but for object vectors. The vector's trailing
87 array is at VEC_OFFSET offset and consists of ELT_SIZE sized
88 elements. */
89
90void *
91vec_o_reserve (void *vec, int reserve, size_t vec_offset, size_t elt_size)
92{
9a3c8263 93 struct vec_prefix *pfx = (struct vec_prefix *) vec;
350da6ee
DJ
94 unsigned alloc = calculate_allocation (pfx, reserve);
95
96 if (!alloc)
97 return NULL;
98
99 vec = xrealloc (vec, vec_offset + alloc * elt_size);
100 ((struct vec_prefix *)vec)->alloc = alloc;
101 if (!pfx)
102 ((struct vec_prefix *)vec)->num = 0;
103
104 return vec;
105}
106
107#if 0
108/* Example uses. */
109DEF_VEC_I (int);
110typedef struct X
111{
112 int i;
113} obj_t;
114typedef obj_t *ptr_t;
115
116DEF_VEC_P (ptr_t);
117DEF_VEC_O (obj_t);
118#endif