xref: /illumos-gate/usr/src/cmd/abi/spectrans/spec2trace/util.c (revision 07c94cbf80ccbba93ea61425c2074f6bfd608a19)
1753d2d2eSraf /*
2753d2d2eSraf  * CDDL HEADER START
3753d2d2eSraf  *
4753d2d2eSraf  * The contents of this file are subject to the terms of the
5753d2d2eSraf  * Common Development and Distribution License, Version 1.0 only
6753d2d2eSraf  * (the "License").  You may not use this file except in compliance
7753d2d2eSraf  * with the License.
8753d2d2eSraf  *
9753d2d2eSraf  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10753d2d2eSraf  * or http://www.opensolaris.org/os/licensing.
11753d2d2eSraf  * See the License for the specific language governing permissions
12753d2d2eSraf  * and limitations under the License.
13753d2d2eSraf  *
14753d2d2eSraf  * When distributing Covered Code, include this CDDL HEADER in each
15753d2d2eSraf  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16753d2d2eSraf  * If applicable, add the following below this CDDL HEADER, with the
17753d2d2eSraf  * fields enclosed by brackets "[]" replaced with your own identifying
18753d2d2eSraf  * information: Portions Copyright [yyyy] [name of copyright owner]
19753d2d2eSraf  *
20753d2d2eSraf  * CDDL HEADER END
21753d2d2eSraf  */
22753d2d2eSraf /*
23753d2d2eSraf  * Copyright 1997-2002 Sun Microsystems, Inc.  All rights reserved.
24753d2d2eSraf  * Use is subject to license terms.
25753d2d2eSraf  */
26753d2d2eSraf 
27753d2d2eSraf #include <stdio.h>
28753d2d2eSraf #include <string.h>
29753d2d2eSraf #include <ctype.h>
30753d2d2eSraf #include <stdlib.h>
31753d2d2eSraf #include "parser.h"
32753d2d2eSraf #include "trace.h"
33753d2d2eSraf #include "util.h"
34753d2d2eSraf #include "errlog.h"
35753d2d2eSraf 
36753d2d2eSraf #define	TABLE_INITIAL	50
37753d2d2eSraf #define	TABLE_INCREMENT	50
38753d2d2eSraf 
39753d2d2eSraf /*
40753d2d2eSraf  * String processing
41753d2d2eSraf  */
42753d2d2eSraf 
43753d2d2eSraf /*
44753d2d2eSraf  * strnormalize -- combined tab-to-space and strtrim, plus removal
45753d2d2eSraf  *	of leading and trailing *$%$^@!!! semicolons.
46753d2d2eSraf  *  Not internationalized: TBD.
47753d2d2eSraf  */
48753d2d2eSraf char *
strnormalize(char * str)49753d2d2eSraf strnormalize(char *str)
50753d2d2eSraf {
51753d2d2eSraf 	char	*p;
52753d2d2eSraf 
53*07c94cbfSToomas Soome 	if (str == NULL || *str == '\0')
54753d2d2eSraf 		return (str);
55*07c94cbfSToomas Soome 	for (p = str; *p != '\0'; p++) {
56753d2d2eSraf 		if (isspace(*p)) {
57753d2d2eSraf 			*p = ' ';
58753d2d2eSraf 		}
59753d2d2eSraf 	}
60753d2d2eSraf 	p--;
61753d2d2eSraf 	while (p >= str && (isspace(*p) || *p == ';'))
62*07c94cbfSToomas Soome 		*p-- = '\0';
63753d2d2eSraf 
64753d2d2eSraf 	/* ERA - remove leading spaces */
65753d2d2eSraf 	while (isspace(*str))
66753d2d2eSraf 		str++;
67753d2d2eSraf 
68753d2d2eSraf 	return (str);
69753d2d2eSraf }
70753d2d2eSraf 
71753d2d2eSraf char *
strtrim(char * str)72753d2d2eSraf strtrim(char *str)
73753d2d2eSraf {
74753d2d2eSraf 	char	*p;
75753d2d2eSraf 
76*07c94cbfSToomas Soome 	for (p = str; *p != '\0'; p++)
77753d2d2eSraf 		continue;
78753d2d2eSraf 	p--;
79753d2d2eSraf 	while (p >= str && isspace(*p))
80*07c94cbfSToomas Soome 		*p-- = '\0';
81753d2d2eSraf 	return (str);
82753d2d2eSraf }
83753d2d2eSraf 
84753d2d2eSraf /*
85753d2d2eSraf  * strlower -- make a string lower-case, destructively.
86753d2d2eSraf  *	Not internationalized: TBD.
87753d2d2eSraf  */
88753d2d2eSraf char *
strlower(char * str)89753d2d2eSraf strlower(char *str)
90753d2d2eSraf {
91753d2d2eSraf 	char	*p;
92753d2d2eSraf 
93*07c94cbfSToomas Soome 	for (p = str; *p != '\0'; p++) {
94753d2d2eSraf 		*p = tolower(*p);
95753d2d2eSraf 	}
96753d2d2eSraf 	return (str);
97753d2d2eSraf }
98753d2d2eSraf 
99753d2d2eSraf /*
100753d2d2eSraf  * strset -- update a dynamically-allocated string or die trying.
101753d2d2eSraf  */
102753d2d2eSraf char *
strset(char * string,char * value)103753d2d2eSraf strset(char *string, char *value)
104753d2d2eSraf {
105753d2d2eSraf 	size_t	vlen;
106753d2d2eSraf 
107753d2d2eSraf 	assert(value != NULL, "passed a NULL value to strset");
108753d2d2eSraf 	vlen = strlen(value);
109753d2d2eSraf 	if (string == NULL) {
110753d2d2eSraf 		/* It was never allocated, so allocate it. */
111753d2d2eSraf 		if ((string = malloc(vlen+1)) == NULL) {
112753d2d2eSraf 			errlog(FATAL, "malloc ran out of space");
113753d2d2eSraf 		}
114753d2d2eSraf 	} else if (strlen(string) < vlen) {
115753d2d2eSraf 
116753d2d2eSraf 		/* Reallocate bigger. */
117753d2d2eSraf 		if ((string = realloc(string, vlen+1)) == NULL) {
118753d2d2eSraf 			errlog(FATAL, "realloc ran out of space", "", 0);
119753d2d2eSraf 		}
120753d2d2eSraf 	}
121753d2d2eSraf 	(void) strcpy(string, value);
122753d2d2eSraf 	return (string);
123753d2d2eSraf }
124753d2d2eSraf 
125753d2d2eSraf /*
126753d2d2eSraf  * in_string_set --see if string matches any member of a space-separated
127753d2d2eSraf  *	set of strings.
128753d2d2eSraf  */
129753d2d2eSraf int
in_string_set(char * p,char * set)130753d2d2eSraf in_string_set(char *p, char *set)
131753d2d2eSraf {
132753d2d2eSraf 	char	*q;
133753d2d2eSraf 	char save;
134753d2d2eSraf 
135753d2d2eSraf 	errlog(BEGIN, "in_string_set( p = \"%s\", set = \"%s\") {", p, set);
136753d2d2eSraf 
137753d2d2eSraf 	for (;;) {
138753d2d2eSraf 		set = skipb(set);
139753d2d2eSraf 		q = nextsep(set);
140753d2d2eSraf 		if (q == set) {
141753d2d2eSraf 			/* We've hit the end */
142753d2d2eSraf 			break;
143753d2d2eSraf 		}
144753d2d2eSraf 		save = *q;
145*07c94cbfSToomas Soome 		*q = '\0';
146753d2d2eSraf 		if (strcmp(p, set) == 0) {
147753d2d2eSraf 			*q = save;
148753d2d2eSraf 			errlog(VERBOSE, "return YES");
149753d2d2eSraf 			errlog(END, "}");
150753d2d2eSraf 			return (YES);
151753d2d2eSraf 		}
152753d2d2eSraf 		*q = save;
153753d2d2eSraf 		set = q;
154753d2d2eSraf 	}
155753d2d2eSraf 	errlog(VERBOSE, "return NO");
156753d2d2eSraf 	errlog(END, "}");
157753d2d2eSraf 	return (NO);
158753d2d2eSraf 
159753d2d2eSraf }
160753d2d2eSraf 
161753d2d2eSraf char *
strend(char * p)162753d2d2eSraf strend(char *p)
163753d2d2eSraf {
164753d2d2eSraf 
165753d2d2eSraf 	while (*p)
166753d2d2eSraf 		p++;
167753d2d2eSraf 	return (p);
168753d2d2eSraf }
169753d2d2eSraf 
170753d2d2eSraf char *
lastspace(char * p)171753d2d2eSraf lastspace(char *p)
172753d2d2eSraf {
173753d2d2eSraf 	char	*q;
174753d2d2eSraf 
175753d2d2eSraf 	q = strend(p);
176753d2d2eSraf 	q--;
177753d2d2eSraf 	while (q >= p && isspace(*q))
178753d2d2eSraf 		q--;
179753d2d2eSraf 	return (++q);
180753d2d2eSraf }
181753d2d2eSraf 
182753d2d2eSraf /*
183753d2d2eSraf  * skipb -- skip over blanks (whitespace, actually), stopping
184753d2d2eSraf  *	on first non-blank.
185753d2d2eSraf  */
186753d2d2eSraf char *
skipb(char * p)187753d2d2eSraf skipb(char *p)
188753d2d2eSraf {
189753d2d2eSraf 	while (*p && isspace(*p))
190753d2d2eSraf 		p++;
191753d2d2eSraf 	return (p);
192753d2d2eSraf }
193753d2d2eSraf 
194753d2d2eSraf /*
195753d2d2eSraf  * nextb -- skip over non-blanks (including operators!)
196753d2d2eSraf  *	stopping on first blank.
197753d2d2eSraf  */
198753d2d2eSraf char *
nextb(char * p)199753d2d2eSraf nextb(char *p)
200753d2d2eSraf {
201753d2d2eSraf 	while (*p && !isspace(*p))
202753d2d2eSraf 		p++;
203753d2d2eSraf 	return (p);
204753d2d2eSraf }
205753d2d2eSraf 
206753d2d2eSraf /*
207753d2d2eSraf  * skipsep -- skip over separators (all but alnum and _),
208753d2d2eSraf  *	stopping on first non-separator.
209753d2d2eSraf  */
210753d2d2eSraf char *
skipsep(char * p)211753d2d2eSraf skipsep(char *p)
212753d2d2eSraf {
213753d2d2eSraf 	errlog(BEGIN, "skipsep() {");
214753d2d2eSraf 	errlog(VERBOSE, "p (in) = %s", p);
215753d2d2eSraf 	while (*p && !(isalnum(*p) || *p == '_' || *p == '$'))
216753d2d2eSraf 		p++;
217753d2d2eSraf 	errlog(VERBOSE, "p (out) = %s", p);
218753d2d2eSraf 	errlog(END, "}");
219753d2d2eSraf 	return (p);
220753d2d2eSraf }
221753d2d2eSraf 
222753d2d2eSraf /*
223753d2d2eSraf  * nextsep -- skip over non-separators (alnum and _, actually),
224753d2d2eSraf  *	stopping on first separator.
225753d2d2eSraf  */
226753d2d2eSraf char *
nextsep(char * p)227753d2d2eSraf nextsep(char *p)
228753d2d2eSraf {
229753d2d2eSraf 	errlog(BEGIN, "nextsep() {");
230753d2d2eSraf 	errlog(VERBOSE, "p (in) = %s", p);
231753d2d2eSraf 	while (*p && isalnum(*p) || *p == '_' || *p == '$')
232753d2d2eSraf 		p++;
233753d2d2eSraf 	errlog(VERBOSE, "p (out) = %s", p);
234753d2d2eSraf 	errlog(END, "}");
235753d2d2eSraf 	return (p);
236753d2d2eSraf }
237753d2d2eSraf 
238753d2d2eSraf /*
239753d2d2eSraf  * nextsep2 -- same as nextsep but also skips '.'
240753d2d2eSraf  */
241753d2d2eSraf char *
nextsep2(char * p)242753d2d2eSraf nextsep2(char *p)
243753d2d2eSraf {
244753d2d2eSraf 	errlog(BEGIN, "nextsep() {");
245753d2d2eSraf 	errlog(VERBOSE, "p (in) = %s", p);
246753d2d2eSraf 	while (*p && isalnum(*p) || *p == '_' || *p == '$' || *p == '.')
247753d2d2eSraf 		p++;
248753d2d2eSraf 	errlog(VERBOSE, "p (out) = %s", p);
249753d2d2eSraf 	errlog(END, "}");
250753d2d2eSraf 	return (p);
251753d2d2eSraf }
252753d2d2eSraf 
253753d2d2eSraf /*
254753d2d2eSraf  * objectname -- basename was taken (in man3c), so...
255753d2d2eSraf  */
256753d2d2eSraf char *
objectname(char * name)257753d2d2eSraf objectname(char *name)
258753d2d2eSraf {
259753d2d2eSraf 	char    *p;
260753d2d2eSraf 	static char basename[MAXLINE];
261753d2d2eSraf 
262753d2d2eSraf 	p = strrchr(name, '/');
263*07c94cbfSToomas Soome 	while (p != NULL && *(p+1) == '\0') {
264753d2d2eSraf 		/* The / was at the end of the name. */
265*07c94cbfSToomas Soome 		*p = '\0';
266753d2d2eSraf 		p = strrchr(name, '/');
267753d2d2eSraf 	}
268753d2d2eSraf 	(void) strlcpy(basename, p? p+1: name, MAXLINE);
269753d2d2eSraf 	if ((p = strstr(basename, ".c")) != NULL) {
270*07c94cbfSToomas Soome 		*p = '\0';
271753d2d2eSraf 	}
272753d2d2eSraf 	return (strcat(basename, ".o"));
273753d2d2eSraf }
274753d2d2eSraf 
275753d2d2eSraf /*
276753d2d2eSraf  * String tables
277753d2d2eSraf  */
278753d2d2eSraf 
279753d2d2eSraf table_t *
create_string_table(int size)280753d2d2eSraf create_string_table(int size)
281753d2d2eSraf {
282753d2d2eSraf 	table_t	*t;
283753d2d2eSraf 
284753d2d2eSraf 	errlog(BEGIN, "create_string_table() {");
285753d2d2eSraf 	if ((t = (table_t *)calloc((size_t)1,
286753d2d2eSraf 	    (size_t)(sizeof (table_t) + (sizeof (char *)*size)))) == NULL) {
287753d2d2eSraf 		errlog(FATAL, "out of memory creating a string table");
288753d2d2eSraf 	}
289753d2d2eSraf 	t->nelem = size;
290753d2d2eSraf 	t->used = -1;
291753d2d2eSraf 	errlog(END, "}");
292753d2d2eSraf 	return (t);
293753d2d2eSraf }
294753d2d2eSraf 
295753d2d2eSraf table_t *
add_string_table(table_t * t,char * value)296753d2d2eSraf add_string_table(table_t *t, char *value)
297753d2d2eSraf {
298753d2d2eSraf 	table_t *t2;
299753d2d2eSraf 	int	i;
300753d2d2eSraf 
301753d2d2eSraf 	if (t == NULL) {
302753d2d2eSraf 		errlog(FATAL, "programmer error: tried to add to "
303753d2d2eSraf 			"a NULL table");
304753d2d2eSraf 	}
305753d2d2eSraf 	if (in_string_table(t, value)) {
306753d2d2eSraf 		return (t);
307753d2d2eSraf 	}
308753d2d2eSraf 	t->used++;
309753d2d2eSraf 	if (t->used >= t->nelem) {
310753d2d2eSraf 		if ((t2 = realloc(t, (size_t)(sizeof (table_t)+(sizeof
311753d2d2eSraf 				(char *)*(t->nelem+TABLE_INCREMENT)))))
312753d2d2eSraf 								== NULL) {
313753d2d2eSraf 			errlog(FATAL, "out of memory extending string table");
314753d2d2eSraf 		}
315753d2d2eSraf 		t = t2;
316753d2d2eSraf 		t->nelem += TABLE_INCREMENT;
317753d2d2eSraf 		for (i = t->used; i < t->nelem; i++) {
318753d2d2eSraf 			t->elements[i] = NULL;
319753d2d2eSraf 		}
320753d2d2eSraf 	}
321753d2d2eSraf 
322753d2d2eSraf 	t->elements[t->used] = strset(t->elements[t->used], value);
323753d2d2eSraf 	return (t);
324753d2d2eSraf }
325753d2d2eSraf 
326753d2d2eSraf /*
327753d2d2eSraf  * free_string_table -- really only mark it empty for reuse.
328753d2d2eSraf  */
329753d2d2eSraf table_t *
free_string_table(table_t * t)330753d2d2eSraf free_string_table(table_t *t)
331753d2d2eSraf {
332753d2d2eSraf 	errlog(BEGIN, "free_string_table() {");
333753d2d2eSraf 	if (t != NULL) {
334753d2d2eSraf 		t->used = -1;
335753d2d2eSraf 	}
336753d2d2eSraf 	errlog(END, "}");
337753d2d2eSraf 	return (t);
338753d2d2eSraf }
339753d2d2eSraf 
340753d2d2eSraf char *
get_string_table(table_t * t,int index)341753d2d2eSraf get_string_table(table_t *t, int index)
342753d2d2eSraf {
343753d2d2eSraf 	if (t == NULL) {
344753d2d2eSraf 		return (NULL);
345753d2d2eSraf 	} else if (index > t->used) {
346753d2d2eSraf 		return (NULL);
347753d2d2eSraf 	} else {
348753d2d2eSraf 		return (t->elements[index]);
349753d2d2eSraf 	}
350753d2d2eSraf }
351753d2d2eSraf 
352753d2d2eSraf int
in_string_table(table_t * t,char * value)353753d2d2eSraf in_string_table(table_t *t, char *value)
354753d2d2eSraf {
355753d2d2eSraf 	int	i;
356753d2d2eSraf 	size_t	len = strlen(value);
357753d2d2eSraf 
358753d2d2eSraf 	if (t == NULL) {
359753d2d2eSraf 		return (0);
360753d2d2eSraf 	}
361753d2d2eSraf 	for (i = 0; i <= t->used; i++) {
362753d2d2eSraf 		if (strncmp(value, t->elements[i], len) == 0 &&
363*07c94cbfSToomas Soome 		    (t->elements[i][len] == '\0' ||
364753d2d2eSraf 			t->elements[i][len] == ','))
365753d2d2eSraf 			return (1);
366753d2d2eSraf 	}
367753d2d2eSraf 	return (0);
368753d2d2eSraf }
369753d2d2eSraf 
370753d2d2eSraf static int
compare(const void * p,const void * q)371753d2d2eSraf compare(const void *p, const void *q)
372753d2d2eSraf {
373753d2d2eSraf 	return (strcmp((char *)(*(char **)p), (char *)(*(char **)q)));
374753d2d2eSraf }
375753d2d2eSraf 
376753d2d2eSraf void
sort_string_table(table_t * t)377753d2d2eSraf sort_string_table(table_t *t)
378753d2d2eSraf {
379753d2d2eSraf 	if (t) {
380753d2d2eSraf 		qsort((char *)t->elements, (size_t)t->used,
381753d2d2eSraf 			sizeof (char *), compare);
382753d2d2eSraf 	}
383753d2d2eSraf }
384