Path: blob/main/cddl/contrib/opensolaris/tools/ctf/cvt/traverse.c
39586 views
/*1* CDDL HEADER START2*3* The contents of this file are subject to the terms of the4* Common Development and Distribution License (the "License").5* You may not use this file except in compliance with the License.6*7* You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE8* or http://www.opensolaris.org/os/licensing.9* See the License for the specific language governing permissions10* and limitations under the License.11*12* When distributing Covered Code, include this CDDL HEADER in each13* file and include the License file at usr/src/OPENSOLARIS.LICENSE.14* If applicable, add the following below this CDDL HEADER, with the15* fields enclosed by brackets "[]" replaced with your own identifying16* information: Portions Copyright [yyyy] [name of copyright owner]17*18* CDDL HEADER END19*/20/*21* Copyright 2006 Sun Microsystems, Inc. All rights reserved.22* Use is subject to license terms.23*/2425#pragma ident "%Z%%M% %I% %E% SMI"2627/*28* Routines used to traverse tdesc trees, invoking user-supplied callbacks29* as the tree is traversed.30*/3132#include <stdio.h>33#include <assert.h>3435#include "ctftools.h"36#include "traverse.h"37#include "memory.h"3839static int (*tddescenders[])(tdesc_t *, tdtrav_data_t *);40static tdtrav_cb_f tdnops[];4142void43tdtrav_init(tdtrav_data_t *tdtd, int *vgenp, tdtrav_cb_f *firstops,44tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)45{46tdtd->vgen = ++(*vgenp);47tdtd->firstops = firstops ? firstops : tdnops;48tdtd->preops = preops ? preops : tdnops;49tdtd->postops = postops ? postops : tdnops;50tdtd->private = private;51}5253static int54tdtrav_plain(tdesc_t *this, tdtrav_data_t *tdtd)55{56return (tdtraverse(this->t_tdesc, &this->t_tdesc, tdtd));57}5859static int60tdtrav_func(tdesc_t *this, tdtrav_data_t *tdtd)61{62fndef_t *fn = this->t_fndef;63int i, rc;6465if ((rc = tdtraverse(fn->fn_ret, &fn->fn_ret, tdtd)) < 0)66return (rc);6768for (i = 0; i < (int) fn->fn_nargs; i++) {69if ((rc = tdtraverse(fn->fn_args[i], &fn->fn_args[i],70tdtd)) < 0)71return (rc);72}7374return (0);75}7677static int78tdtrav_array(tdesc_t *this, tdtrav_data_t *tdtd)79{80ardef_t *ardef = this->t_ardef;81int rc;8283if ((rc = tdtraverse(ardef->ad_contents, &ardef->ad_contents,84tdtd)) < 0)85return (rc);8687return (tdtraverse(ardef->ad_idxtype, &ardef->ad_idxtype, tdtd));88}8990static int91tdtrav_su(tdesc_t *this, tdtrav_data_t *tdtd)92{93mlist_t *ml;94int rc = 0;9596for (ml = this->t_members; ml; ml = ml->ml_next) {97if ((rc = tdtraverse(ml->ml_type, &ml->ml_type, tdtd)) < 0)98return (rc);99}100101return (rc);102}103104/*ARGSUSED*/105int106tdtrav_assert(tdesc_t *node __unused, tdesc_t **nodep __unused, void *private __unused)107{108assert(1 == 0);109110return (-1);111}112113static tdtrav_cb_f tdnops[] = {114NULL,115NULL, /* intrinsic */116NULL, /* pointer */117NULL, /* array */118NULL, /* function */119NULL, /* struct */120NULL, /* union */121NULL, /* enum */122NULL, /* forward */123NULL, /* typedef */124NULL, /* typedef_unres */125NULL, /* volatile */126NULL, /* const */127NULL /* restrict */128};129130static int (*tddescenders[])(tdesc_t *, tdtrav_data_t *) = {131NULL,132NULL, /* intrinsic */133tdtrav_plain, /* pointer */134tdtrav_array, /* array */135tdtrav_func, /* function */136tdtrav_su, /* struct */137tdtrav_su, /* union */138NULL, /* enum */139NULL, /* forward */140tdtrav_plain, /* typedef */141NULL, /* typedef_unres */142tdtrav_plain, /* volatile */143tdtrav_plain, /* const */144tdtrav_plain /* restrict */145};146147int148tdtraverse(tdesc_t *this, tdesc_t **thisp, tdtrav_data_t *tdtd)149{150tdtrav_cb_f travcb;151int (*descender)(tdesc_t *, tdtrav_data_t *);152int descend = 1;153int rc;154155if ((travcb = tdtd->firstops[this->t_type]) != NULL) {156if ((rc = travcb(this, thisp, tdtd->private)) < 0)157return (rc);158else if (rc == 0)159descend = 0;160}161162if (this->t_vgen == tdtd->vgen)163return (1);164this->t_vgen = tdtd->vgen;165166if (descend && (travcb = tdtd->preops[this->t_type]) != NULL) {167if ((rc = travcb(this, thisp, tdtd->private)) < 0)168return (rc);169else if (rc == 0)170descend = 0;171}172173if (descend) {174if ((descender = tddescenders[this->t_type]) != NULL &&175(rc = descender(this, tdtd)) < 0)176return (rc);177178if ((travcb = tdtd->postops[this->t_type]) != NULL &&179(rc = travcb(this, thisp, tdtd->private)) < 0)180return (rc);181}182183return (1);184}185186int187iitraverse_td(void *arg1, void *arg2)188{189iidesc_t *ii = arg1;190tdtrav_data_t *tdtd = arg2;191int i, rc;192193if ((rc = tdtraverse(ii->ii_dtype, &ii->ii_dtype, tdtd)) < 0)194return (rc);195196for (i = 0; i < ii->ii_nargs; i++) {197if ((rc = tdtraverse(ii->ii_args[i], &ii->ii_args[i],198tdtd)) < 0)199return (rc);200}201202return (1);203}204205int206iitraverse(iidesc_t *ii, int *vgenp, tdtrav_cb_f *firstops, tdtrav_cb_f *preops,207tdtrav_cb_f *postops, void *private)208{209tdtrav_data_t tdtd;210211tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);212213return (iitraverse_td(ii, &tdtd));214}215216int217iitraverse_hash(hash_t *iihash, int *vgenp, tdtrav_cb_f *firstops,218tdtrav_cb_f *preops, tdtrav_cb_f *postops, void *private)219{220tdtrav_data_t tdtd;221222tdtrav_init(&tdtd, vgenp, firstops, preops, postops, private);223224return (hash_iter(iihash, iitraverse_td, &tdtd));225}226227228