xref: /titanic_52/usr/src/cmd/abi/spectrans/spec2map/util.c (revision 753d2d2e8e7fd0c9bcf736d9bf2f2faf4d6234cc)
1*753d2d2eSraf /*
2*753d2d2eSraf  * CDDL HEADER START
3*753d2d2eSraf  *
4*753d2d2eSraf  * The contents of this file are subject to the terms of the
5*753d2d2eSraf  * Common Development and Distribution License, Version 1.0 only
6*753d2d2eSraf  * (the "License").  You may not use this file except in compliance
7*753d2d2eSraf  * with the License.
8*753d2d2eSraf  *
9*753d2d2eSraf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*753d2d2eSraf  * or http://www.opensolaris.org/os/licensing.
11*753d2d2eSraf  * See the License for the specific language governing permissions
12*753d2d2eSraf  * and limitations under the License.
13*753d2d2eSraf  *
14*753d2d2eSraf  * When distributing Covered Code, include this CDDL HEADER in each
15*753d2d2eSraf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*753d2d2eSraf  * If applicable, add the following below this CDDL HEADER, with the
17*753d2d2eSraf  * fields enclosed by brackets "[]" replaced with your own identifying
18*753d2d2eSraf  * information: Portions Copyright [yyyy] [name of copyright owner]
19*753d2d2eSraf  *
20*753d2d2eSraf  * CDDL HEADER END
21*753d2d2eSraf  */
22*753d2d2eSraf /*
23*753d2d2eSraf  * Copyright (c) 1997-1999 by Sun Microsystems, Inc.
24*753d2d2eSraf  * All rights reserved.
25*753d2d2eSraf  */
26*753d2d2eSraf #pragma ident	"%Z%%M%	%I%	%E% SMI"
27*753d2d2eSraf 
28*753d2d2eSraf /*
29*753d2d2eSraf  * util.c -- low-level utilities used by map*.c
30*753d2d2eSraf  */
31*753d2d2eSraf #include <stdio.h>
32*753d2d2eSraf #include <string.h>
33*753d2d2eSraf #include <errno.h>
34*753d2d2eSraf #include <stdlib.h>
35*753d2d2eSraf #include "xlator.h"
36*753d2d2eSraf #include "util.h"
37*753d2d2eSraf #include "errlog.h"
38*753d2d2eSraf 
39*753d2d2eSraf /*
40*753d2d2eSraf  * String tables -- WARNING!  This uses realloc to recreate tables,
41*753d2d2eSraf  *	so always assign table_t * return value to the current
42*753d2d2eSraf  *	table pointer, lest the table address change in the
43*753d2d2eSraf  *	called function.
44*753d2d2eSraf  */
45*753d2d2eSraf static char *strset(char *, char *);
46*753d2d2eSraf 
47*753d2d2eSraf table_t *
48*753d2d2eSraf create_stringtable(int size)
49*753d2d2eSraf {
50*753d2d2eSraf 	table_t *t;
51*753d2d2eSraf 
52*753d2d2eSraf 	/* Solaris idiom: malloc && memset. TBD. */
53*753d2d2eSraf 	if ((t = calloc((size_t)1, (size_t)(sizeof (table_t) +
54*753d2d2eSraf 	    ((sizeof (char *)) * size)))) == NULL) {
55*753d2d2eSraf 		errlog(FATAL,
56*753d2d2eSraf 		    "\nOut of memory.\n"
57*753d2d2eSraf 		    "We wish to hold the whole sky,\n"
58*753d2d2eSraf 		    "But we never will.\n");
59*753d2d2eSraf 	}
60*753d2d2eSraf 	t->nelem = size;
61*753d2d2eSraf 	t->used = -1;
62*753d2d2eSraf 	return (t);
63*753d2d2eSraf }
64*753d2d2eSraf 
65*753d2d2eSraf 
66*753d2d2eSraf table_t *
67*753d2d2eSraf add_to_stringtable(table_t *t, char *value)
68*753d2d2eSraf {
69*753d2d2eSraf 	table_t *t2;
70*753d2d2eSraf 
71*753d2d2eSraf 	int i;
72*753d2d2eSraf 
73*753d2d2eSraf 	if (t == NULL) {
74*753d2d2eSraf 		seterrline(__LINE__, __FILE__, NULL, NULL);
75*753d2d2eSraf 		errlog(FATAL|PROGRAM, "programmer error: tried to add to "
76*753d2d2eSraf 			"a NULL table");
77*753d2d2eSraf 	}
78*753d2d2eSraf 	if (in_stringtable(t, value)) {
79*753d2d2eSraf 		return (t);
80*753d2d2eSraf 	}
81*753d2d2eSraf 	++t->used;
82*753d2d2eSraf 	if (t->used >= t->nelem) {
83*753d2d2eSraf 		if ((t2 = realloc(t, (size_t)(sizeof (table_t) +
84*753d2d2eSraf 		    ((sizeof (char *)) * (t->nelem + TABLE_INCREMENT)))))
85*753d2d2eSraf 		    == NULL) {
86*753d2d2eSraf 			print_stringtable(t);
87*753d2d2eSraf 			seterrline(__LINE__, __FILE__, NULL, NULL);
88*753d2d2eSraf 			errlog(FATAL|PROGRAM, "out of memory extending a "
89*753d2d2eSraf 				"string table");
90*753d2d2eSraf 		}
91*753d2d2eSraf 		t = t2;
92*753d2d2eSraf 		t->nelem += TABLE_INCREMENT;
93*753d2d2eSraf 		for (i = t->used; i < t->nelem; ++i) {
94*753d2d2eSraf 			t->elements[i] = NULL;
95*753d2d2eSraf 		}
96*753d2d2eSraf 	}
97*753d2d2eSraf 	t->elements[t->used] = strset(t->elements[t->used], value);
98*753d2d2eSraf 	return (t);
99*753d2d2eSraf }
100*753d2d2eSraf 
101*753d2d2eSraf /*
102*753d2d2eSraf  * free_stringtable -- really only mark it empty for reuse.
103*753d2d2eSraf  */
104*753d2d2eSraf table_t *
105*753d2d2eSraf free_stringtable(table_t *t)
106*753d2d2eSraf {
107*753d2d2eSraf 
108*753d2d2eSraf 	if (t != NULL) {
109*753d2d2eSraf 		t->used = -1;
110*753d2d2eSraf 	}
111*753d2d2eSraf 	return (t);
112*753d2d2eSraf }
113*753d2d2eSraf 
114*753d2d2eSraf 
115*753d2d2eSraf char *
116*753d2d2eSraf get_stringtable(table_t *t, int index)
117*753d2d2eSraf {
118*753d2d2eSraf 
119*753d2d2eSraf 	if (t == NULL) {
120*753d2d2eSraf 		return (NULL);
121*753d2d2eSraf 	} else if (index > t->used) {
122*753d2d2eSraf 		return (NULL);
123*753d2d2eSraf 	} else {
124*753d2d2eSraf 		return (t->elements[index]);
125*753d2d2eSraf 	}
126*753d2d2eSraf }
127*753d2d2eSraf 
128*753d2d2eSraf int
129*753d2d2eSraf in_stringtable(table_t *t, const char *value)
130*753d2d2eSraf {
131*753d2d2eSraf 	int i;
132*753d2d2eSraf 
133*753d2d2eSraf 	if (t == NULL) {
134*753d2d2eSraf 		return (0);
135*753d2d2eSraf 	}
136*753d2d2eSraf 	for (i = 0; i <= t->used; ++i) {
137*753d2d2eSraf 		if (strcmp(value, t->elements[i]) == 0)
138*753d2d2eSraf 			return (1);
139*753d2d2eSraf 	}
140*753d2d2eSraf 	return (0);
141*753d2d2eSraf }
142*753d2d2eSraf 
143*753d2d2eSraf 
144*753d2d2eSraf void
145*753d2d2eSraf print_stringtable(table_t *t)
146*753d2d2eSraf {
147*753d2d2eSraf 	int i;
148*753d2d2eSraf 
149*753d2d2eSraf 	if (t == NULL)
150*753d2d2eSraf 		return;
151*753d2d2eSraf 
152*753d2d2eSraf 	errlog(VERBOSE,
153*753d2d2eSraf 		"table size = %d elements out of %d elements/%d bytes\n",
154*753d2d2eSraf 		t->used + 1, t->nelem,
155*753d2d2eSraf 		sizeof (table_t) + (sizeof (char *) * t->nelem));
156*753d2d2eSraf 
157*753d2d2eSraf 	for (i = 0; i <= t->used; ++i) {
158*753d2d2eSraf 		(void) fprintf(stderr, "\t%s\n",
159*753d2d2eSraf 			get_stringtable(t, i));
160*753d2d2eSraf 	}
161*753d2d2eSraf }
162*753d2d2eSraf 
163*753d2d2eSraf static int
164*753d2d2eSraf compare(const void *p, const void *q)
165*753d2d2eSraf {
166*753d2d2eSraf 	return (strcmp((char *)p, (char *)q));
167*753d2d2eSraf }
168*753d2d2eSraf 
169*753d2d2eSraf void
170*753d2d2eSraf sort_stringtable(table_t *t)
171*753d2d2eSraf {
172*753d2d2eSraf 
173*753d2d2eSraf 	if (t && t->used > 0) {
174*753d2d2eSraf 		qsort((char *)t->elements, (size_t)t->used,
175*753d2d2eSraf 			sizeof (char *), compare);
176*753d2d2eSraf 	}
177*753d2d2eSraf }
178*753d2d2eSraf 
179*753d2d2eSraf 
180*753d2d2eSraf /*
181*753d2d2eSraf  * strset -- update a dynamically-allocated string or die trying.
182*753d2d2eSraf  */
183*753d2d2eSraf /*ARGSUSED*/
184*753d2d2eSraf static char *
185*753d2d2eSraf strset(char *string, char *value)
186*753d2d2eSraf {
187*753d2d2eSraf 	size_t vlen;
188*753d2d2eSraf 
189*753d2d2eSraf 	assert(value != NULL, "passed a null value to strset");
190*753d2d2eSraf 	vlen = strlen(value);
191*753d2d2eSraf 	if (string == NULL) {
192*753d2d2eSraf 		/* It was never allocated, so allocate it. */
193*753d2d2eSraf 		if ((string = malloc(vlen + 1)) == NULL) {
194*753d2d2eSraf 			seterrline(__LINE__, __FILE__, NULL, NULL);
195*753d2d2eSraf 			errlog(FATAL|PROGRAM, "out of memory allocating a "
196*753d2d2eSraf 			    "string");
197*753d2d2eSraf 		}
198*753d2d2eSraf 	} else if (strlen(string) < vlen) {
199*753d2d2eSraf 		/* Reallocate bigger. */
200*753d2d2eSraf 		if ((string = realloc(string, vlen + 1)) == NULL) {
201*753d2d2eSraf 			seterrline(__LINE__, __FILE__, NULL, NULL);
202*753d2d2eSraf 			errlog(FATAL|PROGRAM, "out of memory reallocating"
203*753d2d2eSraf 			    "a string");
204*753d2d2eSraf 		}
205*753d2d2eSraf 	}
206*753d2d2eSraf 	(void) strcpy(string, value);
207*753d2d2eSraf 	return (string);
208*753d2d2eSraf }
209