/* */
This source file includes following definitions.
- varray_open
- varray_assign
- varray_append
- varray_reset
- varray_close
1 /*
2 * Copyright (c) 2004 Tama Communications Corporation
3 *
4 * This file is part of GNU GLOBAL.
5 *
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
23 #ifdef STDC_HEADERS
24 #include <stdlib.h>
25 #endif
26 #include <stdio.h>
27 #include "checkalloc.h"
28 #include "die.h"
29 #include "varray.h"
30
31 /**
32 @file
33
34 Virtual array: usage and memory status
35
36 _: allocated but not assigned. <br>
37 \@: assigned but the value is uncertainty.
38
39 @code
40 Function call Memory status
41 ----------------------------------------------------------
42 (not exist)
43 vb = varray_open(sizeof(int), 5); ||
44
45 int *a = varray_assign(vb, 0, 0); ||
46
47 a == NULL
48
49 int *a = varray_assign(vb, 0, 1); |@|_|_|_|_| // expand
50
51 printf("%d allocated, %d assigned.\n", vb->alloced, vb->length);
52
53 "5 allocated, 1 assigned."
54 v
55 *a = 3; |3|_|_|_|_|
56
57 v
58 int *a = varray_assign(vb, 3, 1); |3|@|@|@|_|
59 v
60 *a = 8; |3|@|@|8|_|
61 v
62 int *a = varray_assign(vb, 5, 1); |3|@|@|8|@|@|_|_|_|_| // expand
63 v
64 *a = 5; |3|@|@|8|@|5|_|_|_|_|
65
66 printf("%d allocated, %d assigned.\n", vb->alloced, vb->length);
67
68 "10 allocated, 6 assigned."
69
70 // After construction, you can treat it as a C array.
71
72 int i, *a = varray_assign(vb, 0, 0);
73
74 for (i = 0; i < vb->length; i++)
75 printf("%d: %d\n", i, a[i]); // a[1], a[2], a[4] is uncertainty.
76
77 @endcode
78 */
79
80 #define DEFAULT_EXPAND 100
81 static int debug = 0;
82 /**
83 * varray_open: open virtual array.
84 *
85 * @param[in] size size of entry
86 * @param[in] expand expand array size <br>
87 * if 0 (zero) is specified then use #DEFAULT_EXPAND.
88 * @return vb #VARRAY structure
89 */
90 VARRAY *
91 varray_open(int size, int expand)
92 {
93 VARRAY *vb = (VARRAY *)check_calloc(sizeof(VARRAY), 1);
94
95 if (size < 1)
96 die("varray_open: size < 1.");
97 if (expand < 0)
98 die("varray_open: expand < 0.");
99 vb->size = size;
100 vb->alloced = vb->length = 0;
101 vb->expand = (expand == 0) ? DEFAULT_EXPAND : expand;
102 vb->vbuf = NULL;
103 return vb;
104 }
105 /**
106 * varray_assign: assign varray entry.
107 *
108 * @param[in] vb #VARRAY structure
109 * @param[in] index index
110 * @param[in] force if entry not found, create it.
111 * @return pointer of the entry
112 *
113 * If specified entry is found then it is returned, else it is allocated
114 * and returned.
115 * This procedure @EMPH{doesn't} operate the contents of the array.
116 */
117 void *
118 varray_assign(VARRAY *vb, int index, int force)
119 {
120 if (index < 0)
121 die("varray_assign: illegal index value.");
122 if (index >= vb->length) {
123 if (force)
124 vb->length = index + 1;
125 else if (index == 0 && vb->length == 0)
126 return NULL;
127 else
128 die("varray_assign: index(=%d) is out of range.", index);
129 }
130 /*
131 * Expand the area.
132 */
133 if (index >= vb->alloced) {
134 int old_alloced = vb->alloced;
135
136 while (index >= vb->alloced)
137 vb->alloced += vb->expand;
138 /*
139 * Old implementations of realloc() may crash
140 * when a null pointer is passed.
141 * Therefore, we cannot use realloc(NULL, ...).
142 */
143 if (vb->vbuf == NULL)
144 vb->vbuf = (char *)check_malloc(vb->size * vb->alloced);
145 else
146 vb->vbuf = (char *)check_realloc(vb->vbuf, vb->size * vb->alloced);
147 if (debug)
148 fprintf(stderr, "Expanded: from %d to %d.\n", old_alloced, vb->alloced);
149 }
150 return (void *)(vb->vbuf + vb->size * index);
151 }
152
153 /**
154 * varray_append: append varray entry.
155 *
156 * @param[in] vb #VARRAY structure
157 * @return pointer of the entry
158 *
159 * This procedure @EMPH{doesn't} operate the contents of the array.
160 */
161 void *
162 varray_append(VARRAY *vb)
163 {
164 return varray_assign(vb, vb->length, 1);
165 }
166 /**
167 * varray_reset: reset varray array.
168 *
169 * @param[in] vb #VARRAY structure
170 */
171 void
172 varray_reset(VARRAY *vb)
173 {
174 vb->length = 0;
175 }
176 /**
177 * varray_close: close varray array.
178 *
179 * @param[in] vb #VARRAY structure
180 */
181 void
182 varray_close(VARRAY *vb)
183 {
184 if (vb) {
185 if (vb->vbuf)
186 (void)free(vb->vbuf);
187 (void)free(vb);
188 }
189 }
/* */