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