Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
freebsd
GitHub Repository: freebsd/freebsd-src
Path: blob/main/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c
39586 views
1
/*
2
* CDDL HEADER START
3
*
4
* The contents of this file are subject to the terms of the
5
* Common Development and Distribution License (the "License").
6
* You may not use this file except in compliance with the License.
7
*
8
* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9
* or http://www.opensolaris.org/os/licensing.
10
* See the License for the specific language governing permissions
11
* and limitations under the License.
12
*
13
* When distributing Covered Code, include this CDDL HEADER in each
14
* file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15
* If applicable, add the following below this CDDL HEADER, with the
16
* fields enclosed by brackets "[]" replaced with your own identifying
17
* information: Portions Copyright [yyyy] [name of copyright owner]
18
*
19
* CDDL HEADER END
20
*/
21
/*
22
* Copyright 2006 Sun Microsystems, Inc. All rights reserved.
23
* Use is subject to license terms.
24
*/
25
26
#pragma ident "%Z%%M% %I% %E% SMI"
27
28
/*
29
* Routines used to traverse tdesc trees, invoking user-supplied callbacks
30
* as the tree is traversed.
31
*/
32
33
#include <stdio.h>
34
#include <assert.h>
35
36
#include "ctftools.h"
37
#include "traverse.h"
38
#include "memory.h"
39
40
static int (*tddescenders[])(tdesc_t *, tdtrav_data_t *);
41
static tdtrav_cb_f tdnops[];
42
43
void
44
tdtrav_init(tdtrav_data_t *tdtd, int *vgenp, tdtrav_cb_f *firstops,
45
tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)
46
{
47
tdtd->vgen = ++(*vgenp);
48
tdtd->firstops = firstops ? firstops : tdnops;
49
tdtd->preops = preops ? preops : tdnops;
50
tdtd->postops = postops ? postops : tdnops;
51
tdtd->private = private;
52
}
53
54
static int
55
tdtrav_plain(tdesc_t *this, tdtrav_data_t *tdtd)
56
{
57
return (tdtraverse(this->t_tdesc, &this->t_tdesc, tdtd));
58
}
59
60
static int
61
tdtrav_func(tdesc_t *this, tdtrav_data_t *tdtd)
62
{
63
fndef_t *fn = this->t_fndef;
64
int i, rc;
65
66
if ((rc = tdtraverse(fn->fn_ret, &fn->fn_ret, tdtd)) < 0)
67
return (rc);
68
69
for (i = 0; i < (int) fn->fn_nargs; i++) {
70
if ((rc = tdtraverse(fn->fn_args[i], &fn->fn_args[i],
71
tdtd)) < 0)
72
return (rc);
73
}
74
75
return (0);
76
}
77
78
static int
79
tdtrav_array(tdesc_t *this, tdtrav_data_t *tdtd)
80
{
81
ardef_t *ardef = this->t_ardef;
82
int rc;
83
84
if ((rc = tdtraverse(ardef->ad_contents, &ardef->ad_contents,
85
tdtd)) < 0)
86
return (rc);
87
88
return (tdtraverse(ardef->ad_idxtype, &ardef->ad_idxtype, tdtd));
89
}
90
91
static int
92
tdtrav_su(tdesc_t *this, tdtrav_data_t *tdtd)
93
{
94
mlist_t *ml;
95
int rc = 0;
96
97
for (ml = this->t_members; ml; ml = ml->ml_next) {
98
if ((rc = tdtraverse(ml->ml_type, &ml->ml_type, tdtd)) < 0)
99
return (rc);
100
}
101
102
return (rc);
103
}
104
105
/*ARGSUSED*/
106
int
107
tdtrav_assert(tdesc_t *node __unused, tdesc_t **nodep __unused, void *private __unused)
108
{
109
assert(1 == 0);
110
111
return (-1);
112
}
113
114
static tdtrav_cb_f tdnops[] = {
115
NULL,
116
NULL, /* intrinsic */
117
NULL, /* pointer */
118
NULL, /* array */
119
NULL, /* function */
120
NULL, /* struct */
121
NULL, /* union */
122
NULL, /* enum */
123
NULL, /* forward */
124
NULL, /* typedef */
125
NULL, /* typedef_unres */
126
NULL, /* volatile */
127
NULL, /* const */
128
NULL /* restrict */
129
};
130
131
static int (*tddescenders[])(tdesc_t *, tdtrav_data_t *) = {
132
NULL,
133
NULL, /* intrinsic */
134
tdtrav_plain, /* pointer */
135
tdtrav_array, /* array */
136
tdtrav_func, /* function */
137
tdtrav_su, /* struct */
138
tdtrav_su, /* union */
139
NULL, /* enum */
140
NULL, /* forward */
141
tdtrav_plain, /* typedef */
142
NULL, /* typedef_unres */
143
tdtrav_plain, /* volatile */
144
tdtrav_plain, /* const */
145
tdtrav_plain /* restrict */
146
};
147
148
int
149
tdtraverse(tdesc_t *this, tdesc_t **thisp, tdtrav_data_t *tdtd)
150
{
151
tdtrav_cb_f travcb;
152
int (*descender)(tdesc_t *, tdtrav_data_t *);
153
int descend = 1;
154
int rc;
155
156
if ((travcb = tdtd->firstops[this->t_type]) != NULL) {
157
if ((rc = travcb(this, thisp, tdtd->private)) < 0)
158
return (rc);
159
else if (rc == 0)
160
descend = 0;
161
}
162
163
if (this->t_vgen == tdtd->vgen)
164
return (1);
165
this->t_vgen = tdtd->vgen;
166
167
if (descend && (travcb = tdtd->preops[this->t_type]) != NULL) {
168
if ((rc = travcb(this, thisp, tdtd->private)) < 0)
169
return (rc);
170
else if (rc == 0)
171
descend = 0;
172
}
173
174
if (descend) {
175
if ((descender = tddescenders[this->t_type]) != NULL &&
176
(rc = descender(this, tdtd)) < 0)
177
return (rc);
178
179
if ((travcb = tdtd->postops[this->t_type]) != NULL &&
180
(rc = travcb(this, thisp, tdtd->private)) < 0)
181
return (rc);
182
}
183
184
return (1);
185
}
186
187
int
188
iitraverse_td(void *arg1, void *arg2)
189
{
190
iidesc_t *ii = arg1;
191
tdtrav_data_t *tdtd = arg2;
192
int i, rc;
193
194
if ((rc = tdtraverse(ii->ii_dtype, &ii->ii_dtype, tdtd)) < 0)
195
return (rc);
196
197
for (i = 0; i < ii->ii_nargs; i++) {
198
if ((rc = tdtraverse(ii->ii_args[i], &ii->ii_args[i],
199
tdtd)) < 0)
200
return (rc);
201
}
202
203
return (1);
204
}
205
206
int
207
iitraverse(iidesc_t *ii, int *vgenp, tdtrav_cb_f *firstops, tdtrav_cb_f *preops,
208
tdtrav_cb_f *postops, void *private)
209
{
210
tdtrav_data_t tdtd;
211
212
tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);
213
214
return (iitraverse_td(ii, &tdtd));
215
}
216
217
int
218
iitraverse_hash(hash_t *iihash, int *vgenp, tdtrav_cb_f *firstops,
219
tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)
220
{
221
tdtrav_data_t tdtd;
222
223
tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);
224
225
return (hash_iter(iihash, iitraverse_td, &tdtd));
226
}
227
228