xref: /titanic_44/usr/src/cmd/abi/spectrans/spec2trace/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 1997-2002 Sun Microsystems, Inc.  All rights reserved.
24*753d2d2eSraf  * Use is subject to license terms.
25*753d2d2eSraf  */
26*753d2d2eSraf 
27*753d2d2eSraf #pragma ident	"%Z%%M%	%I%	%E% SMI"
28*753d2d2eSraf 
29*753d2d2eSraf #include <stdio.h>
30*753d2d2eSraf #include <string.h>
31*753d2d2eSraf #include <ctype.h>
32*753d2d2eSraf #include <stdlib.h>
33*753d2d2eSraf #include "parser.h"
34*753d2d2eSraf #include "trace.h"
35*753d2d2eSraf #include "util.h"
36*753d2d2eSraf #include "errlog.h"
37*753d2d2eSraf 
38*753d2d2eSraf #define	TABLE_INITIAL	50
39*753d2d2eSraf #define	TABLE_INCREMENT	50
40*753d2d2eSraf 
41*753d2d2eSraf /*
42*753d2d2eSraf  * String processing
43*753d2d2eSraf  */
44*753d2d2eSraf 
45*753d2d2eSraf /*
46*753d2d2eSraf  * strnormalize -- combined tab-to-space and strtrim, plus removal
47*753d2d2eSraf  *	of leading and trailing *$%$^@!!! semicolons.
48*753d2d2eSraf  *  Not internationalized: TBD.
49*753d2d2eSraf  */
50*753d2d2eSraf char *
strnormalize(char * str)51*753d2d2eSraf strnormalize(char *str)
52*753d2d2eSraf {
53*753d2d2eSraf 	char	*p;
54*753d2d2eSraf 
55*753d2d2eSraf 	if (str == NULL || *str == NULL)
56*753d2d2eSraf 		return (str);
57*753d2d2eSraf 	for (p = str; *p != NULL; p++) {
58*753d2d2eSraf 		if (isspace(*p)) {
59*753d2d2eSraf 			*p = ' ';
60*753d2d2eSraf 		}
61*753d2d2eSraf 	}
62*753d2d2eSraf 	p--;
63*753d2d2eSraf 	while (p >= str && (isspace(*p) || *p == ';'))
64*753d2d2eSraf 		*p-- = NULL;
65*753d2d2eSraf 
66*753d2d2eSraf 	/* ERA - remove leading spaces */
67*753d2d2eSraf 	while (isspace(*str))
68*753d2d2eSraf 		str++;
69*753d2d2eSraf 
70*753d2d2eSraf 	return (str);
71*753d2d2eSraf }
72*753d2d2eSraf 
73*753d2d2eSraf char *
strtrim(char * str)74*753d2d2eSraf strtrim(char *str)
75*753d2d2eSraf {
76*753d2d2eSraf 	char	*p;
77*753d2d2eSraf 
78*753d2d2eSraf 	for (p = str; *p != NULL; p++)
79*753d2d2eSraf 		continue;
80*753d2d2eSraf 	p--;
81*753d2d2eSraf 	while (p >= str && isspace(*p))
82*753d2d2eSraf 		*p-- = NULL;
83*753d2d2eSraf 	return (str);
84*753d2d2eSraf }
85*753d2d2eSraf 
86*753d2d2eSraf /*
87*753d2d2eSraf  * strlower -- make a string lower-case, destructively.
88*753d2d2eSraf  *	Not internationalized: TBD.
89*753d2d2eSraf  */
90*753d2d2eSraf char *
strlower(char * str)91*753d2d2eSraf strlower(char *str)
92*753d2d2eSraf {
93*753d2d2eSraf 	char	*p;
94*753d2d2eSraf 
95*753d2d2eSraf 	for (p = str; *p != NULL; p++) {
96*753d2d2eSraf 		*p = tolower(*p);
97*753d2d2eSraf 	}
98*753d2d2eSraf 	return (str);
99*753d2d2eSraf }
100*753d2d2eSraf 
101*753d2d2eSraf /*
102*753d2d2eSraf  * strset -- update a dynamically-allocated string or die trying.
103*753d2d2eSraf  */
104*753d2d2eSraf char *
strset(char * string,char * value)105*753d2d2eSraf strset(char *string, char *value)
106*753d2d2eSraf {
107*753d2d2eSraf 	size_t	vlen;
108*753d2d2eSraf 
109*753d2d2eSraf 	assert(value != NULL, "passed a NULL value to strset");
110*753d2d2eSraf 	vlen = strlen(value);
111*753d2d2eSraf 	if (string == NULL) {
112*753d2d2eSraf 		/* It was never allocated, so allocate it. */
113*753d2d2eSraf 		if ((string = malloc(vlen+1)) == NULL) {
114*753d2d2eSraf 			errlog(FATAL, "malloc ran out of space");
115*753d2d2eSraf 		}
116*753d2d2eSraf 	} else if (strlen(string) < vlen) {
117*753d2d2eSraf 
118*753d2d2eSraf 		/* Reallocate bigger. */
119*753d2d2eSraf 		if ((string = realloc(string, vlen+1)) == NULL) {
120*753d2d2eSraf 			errlog(FATAL, "realloc ran out of space", "", 0);
121*753d2d2eSraf 		}
122*753d2d2eSraf 	}
123*753d2d2eSraf 	(void) strcpy(string, value);
124*753d2d2eSraf 	return (string);
125*753d2d2eSraf }
126*753d2d2eSraf 
127*753d2d2eSraf /*
128*753d2d2eSraf  * in_string_set --see if string matches any member of a space-separated
129*753d2d2eSraf  *	set of strings.
130*753d2d2eSraf  */
131*753d2d2eSraf int
in_string_set(char * p,char * set)132*753d2d2eSraf in_string_set(char *p, char *set)
133*753d2d2eSraf {
134*753d2d2eSraf 	char	*q;
135*753d2d2eSraf 	char save;
136*753d2d2eSraf 
137*753d2d2eSraf 	errlog(BEGIN, "in_string_set( p = \"%s\", set = \"%s\") {", p, set);
138*753d2d2eSraf 
139*753d2d2eSraf 	for (;;) {
140*753d2d2eSraf 		set = skipb(set);
141*753d2d2eSraf 		q = nextsep(set);
142*753d2d2eSraf 		if (q == set) {
143*753d2d2eSraf 			/* We've hit the end */
144*753d2d2eSraf 			break;
145*753d2d2eSraf 		}
146*753d2d2eSraf 		save = *q;
147*753d2d2eSraf 		*q = NULL;
148*753d2d2eSraf 		if (strcmp(p, set) == 0) {
149*753d2d2eSraf 			*q = save;
150*753d2d2eSraf 			errlog(VERBOSE, "return YES");
151*753d2d2eSraf 			errlog(END, "}");
152*753d2d2eSraf 			return (YES);
153*753d2d2eSraf 		}
154*753d2d2eSraf 		*q = save;
155*753d2d2eSraf 		set = q;
156*753d2d2eSraf 	}
157*753d2d2eSraf 	errlog(VERBOSE, "return NO");
158*753d2d2eSraf 	errlog(END, "}");
159*753d2d2eSraf 	return (NO);
160*753d2d2eSraf 
161*753d2d2eSraf }
162*753d2d2eSraf 
163*753d2d2eSraf char *
strend(char * p)164*753d2d2eSraf strend(char *p)
165*753d2d2eSraf {
166*753d2d2eSraf 
167*753d2d2eSraf 	while (*p)
168*753d2d2eSraf 		p++;
169*753d2d2eSraf 	return (p);
170*753d2d2eSraf }
171*753d2d2eSraf 
172*753d2d2eSraf char *
lastspace(char * p)173*753d2d2eSraf lastspace(char *p)
174*753d2d2eSraf {
175*753d2d2eSraf 	char	*q;
176*753d2d2eSraf 
177*753d2d2eSraf 	q = strend(p);
178*753d2d2eSraf 	q--;
179*753d2d2eSraf 	while (q >= p && isspace(*q))
180*753d2d2eSraf 		q--;
181*753d2d2eSraf 	return (++q);
182*753d2d2eSraf }
183*753d2d2eSraf 
184*753d2d2eSraf /*
185*753d2d2eSraf  * skipb -- skip over blanks (whitespace, actually), stopping
186*753d2d2eSraf  *	on first non-blank.
187*753d2d2eSraf  */
188*753d2d2eSraf char *
skipb(char * p)189*753d2d2eSraf skipb(char *p)
190*753d2d2eSraf {
191*753d2d2eSraf 	while (*p && isspace(*p))
192*753d2d2eSraf 		p++;
193*753d2d2eSraf 	return (p);
194*753d2d2eSraf }
195*753d2d2eSraf 
196*753d2d2eSraf /*
197*753d2d2eSraf  * nextb -- skip over non-blanks (including operators!)
198*753d2d2eSraf  *	stopping on first blank.
199*753d2d2eSraf  */
200*753d2d2eSraf char *
nextb(char * p)201*753d2d2eSraf nextb(char *p)
202*753d2d2eSraf {
203*753d2d2eSraf 	while (*p && !isspace(*p))
204*753d2d2eSraf 		p++;
205*753d2d2eSraf 	return (p);
206*753d2d2eSraf }
207*753d2d2eSraf 
208*753d2d2eSraf /*
209*753d2d2eSraf  * skipsep -- skip over separators (all but alnum and _),
210*753d2d2eSraf  *	stopping on first non-separator.
211*753d2d2eSraf  */
212*753d2d2eSraf char *
skipsep(char * p)213*753d2d2eSraf skipsep(char *p)
214*753d2d2eSraf {
215*753d2d2eSraf 	errlog(BEGIN, "skipsep() {");
216*753d2d2eSraf 	errlog(VERBOSE, "p (in) = %s", p);
217*753d2d2eSraf 	while (*p && !(isalnum(*p) || *p == '_' || *p == '$'))
218*753d2d2eSraf 		p++;
219*753d2d2eSraf 	errlog(VERBOSE, "p (out) = %s", p);
220*753d2d2eSraf 	errlog(END, "}");
221*753d2d2eSraf 	return (p);
222*753d2d2eSraf }
223*753d2d2eSraf 
224*753d2d2eSraf /*
225*753d2d2eSraf  * nextsep -- skip over non-separators (alnum and _, actually),
226*753d2d2eSraf  *	stopping on first separator.
227*753d2d2eSraf  */
228*753d2d2eSraf char *
nextsep(char * p)229*753d2d2eSraf nextsep(char *p)
230*753d2d2eSraf {
231*753d2d2eSraf 	errlog(BEGIN, "nextsep() {");
232*753d2d2eSraf 	errlog(VERBOSE, "p (in) = %s", p);
233*753d2d2eSraf 	while (*p && isalnum(*p) || *p == '_' || *p == '$')
234*753d2d2eSraf 		p++;
235*753d2d2eSraf 	errlog(VERBOSE, "p (out) = %s", p);
236*753d2d2eSraf 	errlog(END, "}");
237*753d2d2eSraf 	return (p);
238*753d2d2eSraf }
239*753d2d2eSraf 
240*753d2d2eSraf /*
241*753d2d2eSraf  * nextsep2 -- same as nextsep but also skips '.'
242*753d2d2eSraf  */
243*753d2d2eSraf char *
nextsep2(char * p)244*753d2d2eSraf nextsep2(char *p)
245*753d2d2eSraf {
246*753d2d2eSraf 	errlog(BEGIN, "nextsep() {");
247*753d2d2eSraf 	errlog(VERBOSE, "p (in) = %s", p);
248*753d2d2eSraf 	while (*p && isalnum(*p) || *p == '_' || *p == '$' || *p == '.')
249*753d2d2eSraf 		p++;
250*753d2d2eSraf 	errlog(VERBOSE, "p (out) = %s", p);
251*753d2d2eSraf 	errlog(END, "}");
252*753d2d2eSraf 	return (p);
253*753d2d2eSraf }
254*753d2d2eSraf 
255*753d2d2eSraf /*
256*753d2d2eSraf  * objectname -- basename was taken (in man3c), so...
257*753d2d2eSraf  */
258*753d2d2eSraf char *
objectname(char * name)259*753d2d2eSraf objectname(char *name)
260*753d2d2eSraf {
261*753d2d2eSraf 	char    *p;
262*753d2d2eSraf 	static char basename[MAXLINE];
263*753d2d2eSraf 
264*753d2d2eSraf 	p = strrchr(name, '/');
265*753d2d2eSraf 	while (p != NULL && *(p+1) == NULL) {
266*753d2d2eSraf 		/* The / was at the end of the name. */
267*753d2d2eSraf 		*p = NULL;
268*753d2d2eSraf 		p = strrchr(name, '/');
269*753d2d2eSraf 	}
270*753d2d2eSraf 	(void) strlcpy(basename, p? p+1: name, MAXLINE);
271*753d2d2eSraf 	if ((p = strstr(basename, ".c")) != NULL) {
272*753d2d2eSraf 		*p = NULL;
273*753d2d2eSraf 	}
274*753d2d2eSraf 	return (strcat(basename, ".o"));
275*753d2d2eSraf }
276*753d2d2eSraf 
277*753d2d2eSraf /*
278*753d2d2eSraf  * String tables
279*753d2d2eSraf  */
280*753d2d2eSraf 
281*753d2d2eSraf table_t *
create_string_table(int size)282*753d2d2eSraf create_string_table(int size)
283*753d2d2eSraf {
284*753d2d2eSraf 	table_t	*t;
285*753d2d2eSraf 
286*753d2d2eSraf 	errlog(BEGIN, "create_string_table() {");
287*753d2d2eSraf 	if ((t = (table_t *)calloc((size_t)1,
288*753d2d2eSraf 	    (size_t)(sizeof (table_t) + (sizeof (char *)*size)))) == NULL) {
289*753d2d2eSraf 		errlog(FATAL, "out of memory creating a string table");
290*753d2d2eSraf 	}
291*753d2d2eSraf 	t->nelem = size;
292*753d2d2eSraf 	t->used = -1;
293*753d2d2eSraf 	errlog(END, "}");
294*753d2d2eSraf 	return (t);
295*753d2d2eSraf }
296*753d2d2eSraf 
297*753d2d2eSraf table_t *
add_string_table(table_t * t,char * value)298*753d2d2eSraf add_string_table(table_t *t, char *value)
299*753d2d2eSraf {
300*753d2d2eSraf 	table_t *t2;
301*753d2d2eSraf 	int	i;
302*753d2d2eSraf 
303*753d2d2eSraf 	if (t == NULL) {
304*753d2d2eSraf 		errlog(FATAL, "programmer error: tried to add to "
305*753d2d2eSraf 			"a NULL table");
306*753d2d2eSraf 	}
307*753d2d2eSraf 	if (in_string_table(t, value)) {
308*753d2d2eSraf 		return (t);
309*753d2d2eSraf 	}
310*753d2d2eSraf 	t->used++;
311*753d2d2eSraf 	if (t->used >= t->nelem) {
312*753d2d2eSraf 		if ((t2 = realloc(t, (size_t)(sizeof (table_t)+(sizeof
313*753d2d2eSraf 				(char *)*(t->nelem+TABLE_INCREMENT)))))
314*753d2d2eSraf 								== NULL) {
315*753d2d2eSraf 			errlog(FATAL, "out of memory extending string table");
316*753d2d2eSraf 		}
317*753d2d2eSraf 		t = t2;
318*753d2d2eSraf 		t->nelem += TABLE_INCREMENT;
319*753d2d2eSraf 		for (i = t->used; i < t->nelem; i++) {
320*753d2d2eSraf 			t->elements[i] = NULL;
321*753d2d2eSraf 		}
322*753d2d2eSraf 	}
323*753d2d2eSraf 
324*753d2d2eSraf 	t->elements[t->used] = strset(t->elements[t->used], value);
325*753d2d2eSraf 	return (t);
326*753d2d2eSraf }
327*753d2d2eSraf 
328*753d2d2eSraf /*
329*753d2d2eSraf  * free_string_table -- really only mark it empty for reuse.
330*753d2d2eSraf  */
331*753d2d2eSraf table_t *
free_string_table(table_t * t)332*753d2d2eSraf free_string_table(table_t *t)
333*753d2d2eSraf {
334*753d2d2eSraf 	errlog(BEGIN, "free_string_table() {");
335*753d2d2eSraf 	if (t != NULL) {
336*753d2d2eSraf 		t->used = -1;
337*753d2d2eSraf 	}
338*753d2d2eSraf 	errlog(END, "}");
339*753d2d2eSraf 	return (t);
340*753d2d2eSraf }
341*753d2d2eSraf 
342*753d2d2eSraf char *
get_string_table(table_t * t,int index)343*753d2d2eSraf get_string_table(table_t *t, int index)
344*753d2d2eSraf {
345*753d2d2eSraf 	if (t == NULL) {
346*753d2d2eSraf 		return (NULL);
347*753d2d2eSraf 	} else if (index > t->used) {
348*753d2d2eSraf 		return (NULL);
349*753d2d2eSraf 	} else {
350*753d2d2eSraf 		return (t->elements[index]);
351*753d2d2eSraf 	}
352*753d2d2eSraf }
353*753d2d2eSraf 
354*753d2d2eSraf int
in_string_table(table_t * t,char * value)355*753d2d2eSraf in_string_table(table_t *t, char *value)
356*753d2d2eSraf {
357*753d2d2eSraf 	int	i;
358*753d2d2eSraf 	size_t	len = strlen(value);
359*753d2d2eSraf 
360*753d2d2eSraf 	if (t == NULL) {
361*753d2d2eSraf 		return (0);
362*753d2d2eSraf 	}
363*753d2d2eSraf 	for (i = 0; i <= t->used; i++) {
364*753d2d2eSraf 		if (strncmp(value, t->elements[i], len) == 0 &&
365*753d2d2eSraf 		    (t->elements[i][len] == NULL ||
366*753d2d2eSraf 			t->elements[i][len] == ','))
367*753d2d2eSraf 			return (1);
368*753d2d2eSraf 	}
369*753d2d2eSraf 	return (0);
370*753d2d2eSraf }
371*753d2d2eSraf 
372*753d2d2eSraf static int
compare(const void * p,const void * q)373*753d2d2eSraf compare(const void *p, const void *q)
374*753d2d2eSraf {
375*753d2d2eSraf 	return (strcmp((char *)(*(char **)p), (char *)(*(char **)q)));
376*753d2d2eSraf }
377*753d2d2eSraf 
378*753d2d2eSraf void
sort_string_table(table_t * t)379*753d2d2eSraf sort_string_table(table_t *t)
380*753d2d2eSraf {
381*753d2d2eSraf 	if (t) {
382*753d2d2eSraf 		qsort((char *)t->elements, (size_t)t->used,
383*753d2d2eSraf 			sizeof (char *), compare);
384*753d2d2eSraf 	}
385*753d2d2eSraf }
386