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