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 for manipulating iidesc_t structures
30 */
31
32#include <stdio.h>
33#include <stdlib.h>
34#include <strings.h>
35
36#include "ctftools.h"
37#include "memory.h"
38#include "list.h"
39#include "hash.h"
40
41typedef struct iidesc_find {
42	iidesc_t *iif_tgt;
43	iidesc_t *iif_ret;
44} iidesc_find_t;
45
46iidesc_t *
47iidesc_new(char *name)
48{
49	iidesc_t *ii;
50
51	ii = xcalloc(sizeof (iidesc_t));
52	if (name)
53		ii->ii_name = xstrdup(name);
54
55	return (ii);
56}
57
58int
59iidesc_hash(int nbuckets, void *arg)
60{
61	iidesc_t *ii = arg;
62	int h = 0;
63
64	if (ii->ii_name)
65		return (hash_name(nbuckets, ii->ii_name));
66
67	return (h);
68}
69
70static int
71iidesc_cmp(void *arg1, void *arg2)
72{
73	iidesc_t *src = arg1;
74	iidesc_find_t *find = arg2;
75	iidesc_t *tgt = find->iif_tgt;
76
77	if (src->ii_type != tgt->ii_type ||
78	    !streq(src->ii_name, tgt->ii_name))
79		return (0);
80
81	find->iif_ret = src;
82
83	return (-1);
84}
85
86void
87iidesc_add(hash_t *hash, iidesc_t *new)
88{
89	iidesc_find_t find;
90
91	find.iif_tgt = new;
92	find.iif_ret = NULL;
93
94	(void) hash_match(hash, new, iidesc_cmp, &find);
95
96	if (find.iif_ret != NULL) {
97		iidesc_t *old = find.iif_ret;
98		iidesc_t tmp;
99		/* replacing existing one */
100		bcopy(old, &tmp, sizeof (tmp));
101		bcopy(new, old, sizeof (*old));
102		bcopy(&tmp, new, sizeof (*new));
103
104		iidesc_free(new, NULL);
105		return;
106	}
107
108	hash_add(hash, new);
109}
110
111void
112iter_iidescs_by_name(tdata_t *td, char const *name,
113    int (*func)(void *, void *), void *data)
114{
115	iidesc_t tmpdesc;
116	bzero(&tmpdesc, sizeof(tmpdesc));
117	tmpdesc.ii_name = xstrdup(name);
118	(void) hash_match(td->td_iihash, &tmpdesc, func, data);
119	free(tmpdesc.ii_name);
120}
121
122iidesc_t *
123iidesc_dup(iidesc_t *src)
124{
125	iidesc_t *tgt;
126
127	tgt = xmalloc(sizeof (iidesc_t));
128	bcopy(src, tgt, sizeof (iidesc_t));
129
130	tgt->ii_name = src->ii_name ? xstrdup(src->ii_name) : NULL;
131	tgt->ii_owner = src->ii_owner ? xstrdup(src->ii_owner) : NULL;
132
133	if (tgt->ii_nargs) {
134		tgt->ii_args = xmalloc(sizeof (tdesc_t *) * tgt->ii_nargs);
135		bcopy(src->ii_args, tgt->ii_args,
136		    sizeof (tdesc_t *) * tgt->ii_nargs);
137	}
138
139	return (tgt);
140}
141
142iidesc_t *
143iidesc_dup_rename(iidesc_t *src, char const *name, char const *owner)
144{
145	iidesc_t *tgt = iidesc_dup(src);
146	free(tgt->ii_name);
147	free(tgt->ii_owner);
148
149	tgt->ii_name = name ? xstrdup(name) : NULL;
150	tgt->ii_owner = owner ? xstrdup(owner) : NULL;
151
152	return (tgt);
153}
154
155/*ARGSUSED*/
156void
157iidesc_free(void *arg, void *private __unused)
158{
159	iidesc_t *idp = arg;
160	if (idp->ii_name)
161		free(idp->ii_name);
162	if (idp->ii_nargs)
163		free(idp->ii_args);
164	if (idp->ii_owner)
165		free(idp->ii_owner);
166	free(idp);
167}
168
169int
170iidesc_dump(iidesc_t *ii)
171{
172	printf("type: %d  name %s\n", ii->ii_type,
173	    (ii->ii_name ? ii->ii_name : "(anon)"));
174
175	return (0);
176}
177
178int
179iidesc_count_type(void *data, void *private)
180{
181	iidesc_t *ii = data;
182	iitype_t match = (iitype_t)private;
183
184	return (ii->ii_type == match);
185}
186
187void
188iidesc_stats(hash_t *ii)
189{
190	printf("GFun: %5d SFun: %5d GVar: %5d SVar: %5d T %5d SOU: %5d\n",
191	    hash_iter(ii, iidesc_count_type, (void *)II_GFUN),
192	    hash_iter(ii, iidesc_count_type, (void *)II_SFUN),
193	    hash_iter(ii, iidesc_count_type, (void *)II_GVAR),
194	    hash_iter(ii, iidesc_count_type, (void *)II_SVAR),
195	    hash_iter(ii, iidesc_count_type, (void *)II_TYPE),
196	    hash_iter(ii, iidesc_count_type, (void *)II_SOU));
197}
198