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