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