Coverage Report

Created: 2026-04-09 07:01

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/frr/lib/vector.c
Line
Count
Source
1
// SPDX-License-Identifier: GPL-2.0-or-later
2
/* Generic vector interface routine
3
 * Copyright (C) 1997 Kunihiro Ishiguro
4
 */
5
6
#include <zebra.h>
7
8
#include "vector.h"
9
#include "memory.h"
10
11
8
DEFINE_MTYPE_STATIC(LIB, VECTOR, "Vector");
12
8
DEFINE_MTYPE_STATIC(LIB, VECTOR_INDEX, "Vector index");
13
8
14
8
/* Initialize vector : allocate memory and return vector. */
15
8
vector vector_init(unsigned int size)
16
304
{
17
304
  vector v = XCALLOC(MTYPE_VECTOR, sizeof(struct _vector));
18
19
  /* allocate at least one slot */
20
304
  if (size == 0)
21
0
    size = 1;
22
23
304
  v->alloced = size;
24
304
  v->active = 0;
25
304
  v->count = 0;
26
304
  v->index = XCALLOC(MTYPE_VECTOR_INDEX, sizeof(void *) * size);
27
304
  return v;
28
304
}
29
30
void vector_free(vector v)
31
0
{
32
0
  XFREE(MTYPE_VECTOR_INDEX, v->index);
33
0
  XFREE(MTYPE_VECTOR, v);
34
0
}
35
36
vector vector_copy(vector v)
37
0
{
38
0
  unsigned int size;
39
0
  vector new = XCALLOC(MTYPE_VECTOR, sizeof(struct _vector));
40
41
0
  new->active = v->active;
42
0
  new->alloced = v->alloced;
43
0
  new->count = v->count;
44
45
0
  size = sizeof(void *) * (v->alloced);
46
0
  new->index = XCALLOC(MTYPE_VECTOR_INDEX, size);
47
0
  memcpy(new->index, v->index, size);
48
49
0
  return new;
50
0
}
51
52
/* Check assigned index, and if it runs short double index pointer */
53
void vector_ensure(vector v, unsigned int num)
54
158
{
55
158
  if (v->alloced > num)
56
130
    return;
57
58
28
  v->index = XREALLOC(MTYPE_VECTOR_INDEX, v->index,
59
28
          sizeof(void *) * (v->alloced * 2));
60
28
  memset(&v->index[v->alloced], 0, sizeof(void *) * v->alloced);
61
28
  v->alloced *= 2;
62
63
28
  if (v->alloced <= num)
64
8
    vector_ensure(v, num);
65
28
}
66
67
/* This function only returns next empty slot index.  It dose not mean
68
   the slot's index memory is assigned, please call vector_ensure()
69
   after calling this function. */
70
int vector_empty_slot(vector v)
71
75
{
72
75
  unsigned int i;
73
74
75
  if (v->active == v->count)
75
75
    return v->active;
76
77
0
  if (v->active == 0)
78
0
    return 0;
79
80
0
  for (i = 0; i < v->active; i++)
81
0
    if (v->index[i] == 0)
82
0
      return i;
83
84
0
  return i;
85
0
}
86
87
/* Set value to the smallest empty slot. */
88
int vector_set(vector v, void *val)
89
75
{
90
75
  unsigned int i;
91
92
75
  i = vector_empty_slot(v);
93
75
  vector_ensure(v, i);
94
95
75
  if (v->index[i])
96
0
    v->count--;
97
75
  if (val)
98
75
    v->count++;
99
75
  v->index[i] = val;
100
101
75
  if (v->active <= i)
102
75
    v->active = i + 1;
103
104
75
  return i;
105
75
}
106
107
/* Set value to specified index slot. */
108
int vector_set_index(vector v, unsigned int i, void *val)
109
75
{
110
75
  vector_ensure(v, i);
111
112
75
  if (v->index[i])
113
0
    v->count--;
114
75
  if (val)
115
75
    v->count++;
116
75
  v->index[i] = val;
117
118
75
  if (v->active <= i)
119
21
    v->active = i + 1;
120
121
75
  return i;
122
75
}
123
124
/* Look up vector.  */
125
void *vector_lookup(vector v, unsigned int i)
126
0
{
127
0
  if (i >= v->active)
128
0
    return NULL;
129
0
  return v->index[i];
130
0
}
131
132
/* Lookup vector, ensure it. */
133
void *vector_lookup_ensure(vector v, unsigned int i)
134
0
{
135
0
  vector_ensure(v, i);
136
0
  return v->index[i];
137
0
}
138
139
/* Unset value at specified index slot. */
140
void vector_unset(vector v, unsigned int i)
141
0
{
142
0
  if (i >= v->alloced)
143
0
    return;
144
145
0
  if (v->index[i])
146
0
    v->count--;
147
148
0
  v->index[i] = NULL;
149
150
0
  if (i + 1 == v->active) {
151
0
    v->active--;
152
0
    while (i && v->index[--i] == NULL && v->active--)
153
0
      ; /* Is this ugly ? */
154
0
  }
155
0
}
156
157
void vector_remove(vector v, unsigned int ix)
158
0
{
159
0
  if (ix >= v->active)
160
0
    return;
161
162
0
  if (v->index[ix])
163
0
    v->count--;
164
165
0
  int n = (--v->active) - ix;
166
167
0
  memmove(&v->index[ix], &v->index[ix + 1], n * sizeof(void *));
168
0
  v->index[v->active] = NULL;
169
0
}
170
171
void vector_compact(vector v)
172
0
{
173
0
  for (unsigned int i = 0; i < vector_active(v); ++i) {
174
0
    if (vector_slot(v, i) == NULL) {
175
0
      vector_remove(v, i);
176
0
      --i;
177
0
    }
178
0
  }
179
0
}
180
181
void vector_unset_value(vector v, void *val)
182
0
{
183
0
  size_t i;
184
185
0
  for (i = 0; i < v->active; i++)
186
0
    if (v->index[i] == val) {
187
0
      v->index[i] = NULL;
188
0
      v->count--;
189
0
      break;
190
0
    }
191
192
0
  if (i + 1 == v->active)
193
0
    do
194
0
      v->active--;
195
0
    while (i && v->index[--i] == NULL);
196
0
}
197
198
void vector_to_array(vector v, void ***dest, int *argc)
199
0
{
200
0
  *dest = XCALLOC(MTYPE_TMP, sizeof(void *) * v->active);
201
0
  memcpy(*dest, v->index, sizeof(void *) * v->active);
202
0
  *argc = v->active;
203
0
}
204
205
vector array_to_vector(void **src, int argc)
206
0
{
207
0
  vector v = vector_init(VECTOR_MIN_SIZE);
208
209
0
  for (int i = 0; i < argc; i++)
210
0
    vector_set_index(v, i, src[i]);
211
0
  return v;
212
0
}