1178481Sjb/*
2178481Sjb * CDDL HEADER START
3178481Sjb *
4178481Sjb * The contents of this file are subject to the terms of the
5178481Sjb * Common Development and Distribution License (the "License").
6178481Sjb * You may not use this file except in compliance with the License.
7178481Sjb *
8178481Sjb * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
9178481Sjb * or http://www.opensolaris.org/os/licensing.
10178481Sjb * See the License for the specific language governing permissions
11178481Sjb * and limitations under the License.
12178481Sjb *
13178481Sjb * When distributing Covered Code, include this CDDL HEADER in each
14178481Sjb * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
15178481Sjb * If applicable, add the following below this CDDL HEADER, with the
16178481Sjb * fields enclosed by brackets "[]" replaced with your own identifying
17178481Sjb * information: Portions Copyright [yyyy] [name of copyright owner]
18178481Sjb *
19178481Sjb * CDDL HEADER END
20178481Sjb */
21178481Sjb/*
22178481Sjb * Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
23178481Sjb * Use is subject to license terms.
24178481Sjb */
25178481Sjb
26178481Sjb#pragma ident	"%Z%%M%	%I%	%E% SMI"
27178481Sjb
28178481Sjb/*
29178481Sjb * Routines used to traverse tdesc trees, invoking user-supplied callbacks
30178481Sjb * as the tree is traversed.
31178481Sjb */
32178481Sjb
33178481Sjb#include <stdio.h>
34178481Sjb#include <assert.h>
35178481Sjb
36178481Sjb#include "ctftools.h"
37178481Sjb#include "traverse.h"
38178481Sjb#include "memory.h"
39178481Sjb
40249656Sedstatic int (*tddescenders[])(tdesc_t *, tdtrav_data_t *);
41249656Sedstatic tdtrav_cb_f tdnops[];
42178481Sjb
43178481Sjbvoid
44178481Sjbtdtrav_init(tdtrav_data_t *tdtd, int *vgenp, tdtrav_cb_f *firstops,
45178481Sjb    tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)
46178481Sjb{
47178481Sjb	tdtd->vgen = ++(*vgenp);
48178481Sjb	tdtd->firstops = firstops ? firstops : tdnops;
49178481Sjb	tdtd->preops = preops ? preops : tdnops;
50178481Sjb	tdtd->postops = postops ? postops : tdnops;
51178481Sjb	tdtd->private = private;
52178481Sjb}
53178481Sjb
54178481Sjbstatic int
55178481Sjbtdtrav_plain(tdesc_t *this, tdtrav_data_t *tdtd)
56178481Sjb{
57178481Sjb	return (tdtraverse(this->t_tdesc, &this->t_tdesc, tdtd));
58178481Sjb}
59178481Sjb
60178481Sjbstatic int
61178481Sjbtdtrav_func(tdesc_t *this, tdtrav_data_t *tdtd)
62178481Sjb{
63178481Sjb	fndef_t *fn = this->t_fndef;
64178481Sjb	int i, rc;
65178481Sjb
66178481Sjb	if ((rc = tdtraverse(fn->fn_ret, &fn->fn_ret, tdtd)) < 0)
67178481Sjb		return (rc);
68178481Sjb
69178546Sjb	for (i = 0; i < (int) fn->fn_nargs; i++) {
70178481Sjb		if ((rc = tdtraverse(fn->fn_args[i], &fn->fn_args[i],
71178481Sjb		    tdtd)) < 0)
72178481Sjb			return (rc);
73178481Sjb	}
74178481Sjb
75178481Sjb	return (0);
76178481Sjb}
77178481Sjb
78178481Sjbstatic int
79178481Sjbtdtrav_array(tdesc_t *this, tdtrav_data_t *tdtd)
80178481Sjb{
81178481Sjb	ardef_t *ardef = this->t_ardef;
82178481Sjb	int rc;
83178481Sjb
84178481Sjb	if ((rc = tdtraverse(ardef->ad_contents, &ardef->ad_contents,
85178481Sjb	    tdtd)) < 0)
86178481Sjb		return (rc);
87178481Sjb
88178481Sjb	return (tdtraverse(ardef->ad_idxtype, &ardef->ad_idxtype, tdtd));
89178481Sjb}
90178481Sjb
91178481Sjbstatic int
92178481Sjbtdtrav_su(tdesc_t *this, tdtrav_data_t *tdtd)
93178481Sjb{
94178481Sjb	mlist_t *ml;
95178481Sjb	int rc = 0;
96178481Sjb
97178481Sjb	for (ml = this->t_members; ml; ml = ml->ml_next) {
98178481Sjb		if ((rc = tdtraverse(ml->ml_type, &ml->ml_type, tdtd)) < 0)
99178481Sjb			return (rc);
100178481Sjb	}
101178481Sjb
102178481Sjb	return (rc);
103178481Sjb}
104178481Sjb
105178481Sjb/*ARGSUSED*/
106178481Sjbint
107178546Sjbtdtrav_assert(tdesc_t *node __unused, tdesc_t **nodep __unused, void *private __unused)
108178481Sjb{
109178481Sjb	assert(1 == 0);
110178481Sjb
111178481Sjb	return (-1);
112178481Sjb}
113178481Sjb
114249656Sedstatic tdtrav_cb_f tdnops[] = {
115178481Sjb	NULL,
116178481Sjb	NULL,			/* intrinsic */
117178481Sjb	NULL,			/* pointer */
118178481Sjb	NULL,			/* array */
119178481Sjb	NULL,			/* function */
120178481Sjb	NULL,			/* struct */
121178481Sjb	NULL,			/* union */
122178481Sjb	NULL,			/* enum */
123178481Sjb	NULL,			/* forward */
124178481Sjb	NULL,			/* typedef */
125178481Sjb	NULL,			/* typedef_unres */
126178481Sjb	NULL,			/* volatile */
127178481Sjb	NULL,			/* const */
128178481Sjb	NULL			/* restrict */
129178481Sjb};
130178481Sjb
131249656Sedstatic int (*tddescenders[])(tdesc_t *, tdtrav_data_t *) = {
132178481Sjb	NULL,
133178481Sjb	NULL,			/* intrinsic */
134178481Sjb	tdtrav_plain,		/* pointer */
135178481Sjb	tdtrav_array,		/* array */
136178481Sjb	tdtrav_func,		/* function */
137178481Sjb	tdtrav_su,		/* struct */
138178481Sjb	tdtrav_su,		/* union */
139178481Sjb	NULL,			/* enum */
140178481Sjb	NULL,			/* forward */
141178481Sjb	tdtrav_plain,		/* typedef */
142178481Sjb	NULL,			/* typedef_unres */
143178481Sjb	tdtrav_plain,		/* volatile */
144178481Sjb	tdtrav_plain,		/* const */
145178481Sjb	tdtrav_plain		/* restrict */
146178481Sjb};
147178481Sjb
148178481Sjbint
149178481Sjbtdtraverse(tdesc_t *this, tdesc_t **thisp, tdtrav_data_t *tdtd)
150178481Sjb{
151178481Sjb	tdtrav_cb_f travcb;
152178546Sjb	int (*descender)(tdesc_t *, tdtrav_data_t *);
153178481Sjb	int descend = 1;
154178481Sjb	int rc;
155178481Sjb
156178481Sjb	if ((travcb = tdtd->firstops[this->t_type]) != NULL) {
157178481Sjb		if ((rc = travcb(this, thisp, tdtd->private)) < 0)
158178481Sjb			return (rc);
159178481Sjb		else if (rc == 0)
160178481Sjb			descend = 0;
161178481Sjb	}
162178481Sjb
163178481Sjb	if (this->t_vgen == tdtd->vgen)
164178481Sjb		return (1);
165178481Sjb	this->t_vgen = tdtd->vgen;
166178481Sjb
167178481Sjb	if (descend && (travcb = tdtd->preops[this->t_type]) != NULL) {
168178481Sjb		if ((rc = travcb(this, thisp, tdtd->private)) < 0)
169178481Sjb			return (rc);
170178481Sjb		else if (rc == 0)
171178481Sjb			descend = 0;
172178481Sjb	}
173178481Sjb
174178481Sjb	if (descend) {
175178481Sjb		if ((descender = tddescenders[this->t_type]) != NULL &&
176178481Sjb		    (rc = descender(this, tdtd)) < 0)
177178481Sjb			return (rc);
178178481Sjb
179178481Sjb		if ((travcb = tdtd->postops[this->t_type]) != NULL &&
180178481Sjb		    (rc = travcb(this, thisp, tdtd->private)) < 0)
181178481Sjb			return (rc);
182178481Sjb	}
183178481Sjb
184178481Sjb	return (1);
185178481Sjb}
186178481Sjb
187178481Sjbint
188178546Sjbiitraverse_td(void *arg1, void *arg2)
189178481Sjb{
190178546Sjb	iidesc_t *ii = arg1;
191178546Sjb	tdtrav_data_t *tdtd = arg2;
192178481Sjb	int i, rc;
193178481Sjb
194178481Sjb	if ((rc = tdtraverse(ii->ii_dtype, &ii->ii_dtype, tdtd)) < 0)
195178481Sjb		return (rc);
196178481Sjb
197178481Sjb	for (i = 0; i < ii->ii_nargs; i++) {
198178481Sjb		if ((rc = tdtraverse(ii->ii_args[i], &ii->ii_args[i],
199178481Sjb		    tdtd)) < 0)
200178481Sjb			return (rc);
201178481Sjb	}
202178481Sjb
203178481Sjb	return (1);
204178481Sjb}
205178481Sjb
206178481Sjbint
207178481Sjbiitraverse(iidesc_t *ii, int *vgenp, tdtrav_cb_f *firstops, tdtrav_cb_f *preops,
208178481Sjb    tdtrav_cb_f *postops, void *private)
209178481Sjb{
210178481Sjb	tdtrav_data_t tdtd;
211178481Sjb
212178481Sjb	tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);
213178481Sjb
214178481Sjb	return (iitraverse_td(ii, &tdtd));
215178481Sjb}
216178481Sjb
217178481Sjbint
218178481Sjbiitraverse_hash(hash_t *iihash, int *vgenp, tdtrav_cb_f *firstops,
219178481Sjb    tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)
220178481Sjb{
221178481Sjb	tdtrav_data_t tdtd;
222178481Sjb
223178481Sjb	tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);
224178481Sjb
225178546Sjb	return (hash_iter(iihash, iitraverse_td, &tdtd));
226178481Sjb}
227