1*0Sstevel@tonic-gate /*
2*0Sstevel@tonic-gate * CDDL HEADER START
3*0Sstevel@tonic-gate *
4*0Sstevel@tonic-gate * The contents of this file are subject to the terms of the
5*0Sstevel@tonic-gate * Common Development and Distribution License, Version 1.0 only
6*0Sstevel@tonic-gate * (the "License"). You may not use this file except in compliance
7*0Sstevel@tonic-gate * with the License.
8*0Sstevel@tonic-gate *
9*0Sstevel@tonic-gate * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*0Sstevel@tonic-gate * or http://www.opensolaris.org/os/licensing.
11*0Sstevel@tonic-gate * See the License for the specific language governing permissions
12*0Sstevel@tonic-gate * and limitations under the License.
13*0Sstevel@tonic-gate *
14*0Sstevel@tonic-gate * When distributing Covered Code, include this CDDL HEADER in each
15*0Sstevel@tonic-gate * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*0Sstevel@tonic-gate * If applicable, add the following below this CDDL HEADER, with the
17*0Sstevel@tonic-gate * fields enclosed by brackets "[]" replaced with your own identifying
18*0Sstevel@tonic-gate * information: Portions Copyright [yyyy] [name of copyright owner]
19*0Sstevel@tonic-gate *
20*0Sstevel@tonic-gate * CDDL HEADER END
21*0Sstevel@tonic-gate */
22*0Sstevel@tonic-gate /*
23*0Sstevel@tonic-gate * Copyright 1996-2002 Sun Microsystems, Inc. All rights reserved.
24*0Sstevel@tonic-gate * Use is subject to license terms.
25*0Sstevel@tonic-gate */
26*0Sstevel@tonic-gate
27*0Sstevel@tonic-gate #pragma ident "%Z%%M% %I% %E% SMI"
28*0Sstevel@tonic-gate
29*0Sstevel@tonic-gate #include <unistd.h>
30*0Sstevel@tonic-gate #include <math.h>
31*0Sstevel@tonic-gate #include <stdlib.h>
32*0Sstevel@tonic-gate #include "stabs.h"
33*0Sstevel@tonic-gate
34*0Sstevel@tonic-gate int debug_level = 0;
35*0Sstevel@tonic-gate int line;
36*0Sstevel@tonic-gate
37*0Sstevel@tonic-gate boolean_t error = B_FALSE;
38*0Sstevel@tonic-gate char *program = NULL;
39*0Sstevel@tonic-gate
40*0Sstevel@tonic-gate extern void forth_do_sou(struct tdesc *, struct node *);
41*0Sstevel@tonic-gate extern void forth_do_enum(struct tdesc *, struct node *);
42*0Sstevel@tonic-gate extern void forth_do_intrinsic(struct tdesc *, struct node *);
43*0Sstevel@tonic-gate extern void genassym_do_sou(struct tdesc *, struct node *);
44*0Sstevel@tonic-gate extern void genassym_do_enum(struct tdesc *, struct node *);
45*0Sstevel@tonic-gate extern void genassym_do_intrinsic(struct tdesc *, struct node *);
46*0Sstevel@tonic-gate extern void squander_do_sou(struct tdesc *, struct node *);
47*0Sstevel@tonic-gate extern void squander_do_enum(struct tdesc *, struct node *);
48*0Sstevel@tonic-gate extern void squander_do_intrinsic(struct tdesc *, struct node *);
49*0Sstevel@tonic-gate
50*0Sstevel@tonic-gate struct model_info models[] = {
51*0Sstevel@tonic-gate { "ilp32", 4, 1, 2, 4, 4 },
52*0Sstevel@tonic-gate { "lp64", 8, 1, 2, 4, 8 },
53*0Sstevel@tonic-gate { NULL, 0, 0, 0 }
54*0Sstevel@tonic-gate };
55*0Sstevel@tonic-gate
56*0Sstevel@tonic-gate struct stab_ops {
57*0Sstevel@tonic-gate char *type;
58*0Sstevel@tonic-gate void (*do_sou)(struct tdesc *, struct node *);
59*0Sstevel@tonic-gate void (*do_enum)(struct tdesc *, struct node *);
60*0Sstevel@tonic-gate void (*do_intrinsic)(struct tdesc *, struct node *);
61*0Sstevel@tonic-gate } ops_table[] = {
62*0Sstevel@tonic-gate { "forth",
63*0Sstevel@tonic-gate forth_do_sou, forth_do_enum, forth_do_intrinsic },
64*0Sstevel@tonic-gate { "genassym",
65*0Sstevel@tonic-gate genassym_do_sou, genassym_do_enum, genassym_do_intrinsic },
66*0Sstevel@tonic-gate { "squander",
67*0Sstevel@tonic-gate squander_do_sou, squander_do_enum, squander_do_intrinsic },
68*0Sstevel@tonic-gate { NULL, NULL, NULL }
69*0Sstevel@tonic-gate };
70*0Sstevel@tonic-gate
71*0Sstevel@tonic-gate static void get_dbgs(int argc, char **argv);
72*0Sstevel@tonic-gate static void parse_dbg(FILE *sp);
73*0Sstevel@tonic-gate static void printnode(struct node *np);
74*0Sstevel@tonic-gate static struct tdesc *find_member(struct tdesc *tdp, char *name);
75*0Sstevel@tonic-gate static char *namex(char *cp, char **w);
76*0Sstevel@tonic-gate static void addchild(char *cp, struct node *np);
77*0Sstevel@tonic-gate static struct node *getnode(char *cp);
78*0Sstevel@tonic-gate
79*0Sstevel@tonic-gate struct stab_ops *ops;
80*0Sstevel@tonic-gate struct model_info *model;
81*0Sstevel@tonic-gate
82*0Sstevel@tonic-gate int
main(int argc,char ** argv)83*0Sstevel@tonic-gate main(int argc, char **argv)
84*0Sstevel@tonic-gate {
85*0Sstevel@tonic-gate char *output_type = NULL;
86*0Sstevel@tonic-gate char *model_name = NULL;
87*0Sstevel@tonic-gate int c;
88*0Sstevel@tonic-gate
89*0Sstevel@tonic-gate program = strrchr(argv[0], '/');
90*0Sstevel@tonic-gate if (program != NULL)
91*0Sstevel@tonic-gate program++;
92*0Sstevel@tonic-gate else
93*0Sstevel@tonic-gate program = argv[0];
94*0Sstevel@tonic-gate
95*0Sstevel@tonic-gate /* defaults */
96*0Sstevel@tonic-gate output_type = "forth";
97*0Sstevel@tonic-gate model_name = "ilp32";
98*0Sstevel@tonic-gate
99*0Sstevel@tonic-gate while (!error && ((c = getopt(argc, argv, "dt:m:")) != EOF)) {
100*0Sstevel@tonic-gate switch (c) {
101*0Sstevel@tonic-gate case 't':
102*0Sstevel@tonic-gate output_type = optarg;
103*0Sstevel@tonic-gate break;
104*0Sstevel@tonic-gate case 'm':
105*0Sstevel@tonic-gate model_name = optarg;
106*0Sstevel@tonic-gate break;
107*0Sstevel@tonic-gate case 'd':
108*0Sstevel@tonic-gate debug_level++;
109*0Sstevel@tonic-gate break;
110*0Sstevel@tonic-gate case '?':
111*0Sstevel@tonic-gate default:
112*0Sstevel@tonic-gate error = B_TRUE;
113*0Sstevel@tonic-gate break;
114*0Sstevel@tonic-gate }
115*0Sstevel@tonic-gate }
116*0Sstevel@tonic-gate
117*0Sstevel@tonic-gate if (!error) {
118*0Sstevel@tonic-gate /*
119*0Sstevel@tonic-gate * Find ops for the specified output type
120*0Sstevel@tonic-gate */
121*0Sstevel@tonic-gate for (ops = ops_table; ops->type != NULL; ops++) {
122*0Sstevel@tonic-gate if (strcmp(ops->type, output_type) == 0)
123*0Sstevel@tonic-gate break;
124*0Sstevel@tonic-gate }
125*0Sstevel@tonic-gate if (ops->type == NULL)
126*0Sstevel@tonic-gate error = B_TRUE;
127*0Sstevel@tonic-gate }
128*0Sstevel@tonic-gate
129*0Sstevel@tonic-gate if (!error) {
130*0Sstevel@tonic-gate /*
131*0Sstevel@tonic-gate * Find model characteristics
132*0Sstevel@tonic-gate */
133*0Sstevel@tonic-gate for (model = models; model->name != NULL; model++) {
134*0Sstevel@tonic-gate if (strcmp(model->name, model_name) == 0)
135*0Sstevel@tonic-gate break;
136*0Sstevel@tonic-gate }
137*0Sstevel@tonic-gate if (model->name == NULL)
138*0Sstevel@tonic-gate error = B_TRUE;
139*0Sstevel@tonic-gate }
140*0Sstevel@tonic-gate
141*0Sstevel@tonic-gate /* skip over previously processed arguments */
142*0Sstevel@tonic-gate argc -= optind;
143*0Sstevel@tonic-gate argv += optind;
144*0Sstevel@tonic-gate if (argc < 1)
145*0Sstevel@tonic-gate error = B_TRUE;
146*0Sstevel@tonic-gate
147*0Sstevel@tonic-gate if (error) {
148*0Sstevel@tonic-gate fprintf(stderr, "Usage: %s [-d] {-m datamodel} "
149*0Sstevel@tonic-gate "{-t output_type} files\n", program);
150*0Sstevel@tonic-gate fprintf(stderr, "\tSupported data models:\n");
151*0Sstevel@tonic-gate for (model = models; model->name != NULL; model++)
152*0Sstevel@tonic-gate fprintf(stderr, "\t\t%s\n", model->name);
153*0Sstevel@tonic-gate fprintf(stderr, "\tSupported output types:\n");
154*0Sstevel@tonic-gate for (ops = ops_table; ops->type != NULL; ops++)
155*0Sstevel@tonic-gate fprintf(stderr, "\t\t%s\n", ops->type);
156*0Sstevel@tonic-gate return (1);
157*0Sstevel@tonic-gate }
158*0Sstevel@tonic-gate
159*0Sstevel@tonic-gate parse_input();
160*0Sstevel@tonic-gate
161*0Sstevel@tonic-gate get_dbgs(argc, argv);
162*0Sstevel@tonic-gate
163*0Sstevel@tonic-gate return (error ? 1 : 0);
164*0Sstevel@tonic-gate }
165*0Sstevel@tonic-gate
166*0Sstevel@tonic-gate /*
167*0Sstevel@tonic-gate * This routine will read the .dbg files and build a list of the structures
168*0Sstevel@tonic-gate * and fields that user is interested in. Any struct specified will get all
169*0Sstevel@tonic-gate * its fields included. If nested struct needs to be printed - then the
170*0Sstevel@tonic-gate * field name and name of struct type needs to be included in the next line.
171*0Sstevel@tonic-gate */
172*0Sstevel@tonic-gate static void
get_dbgs(int argc,char ** argv)173*0Sstevel@tonic-gate get_dbgs(int argc, char **argv)
174*0Sstevel@tonic-gate {
175*0Sstevel@tonic-gate FILE *fp;
176*0Sstevel@tonic-gate
177*0Sstevel@tonic-gate for (; argc != 0; argc--, argv++) {
178*0Sstevel@tonic-gate if ((fp = fopen(*argv, "r")) == NULL) {
179*0Sstevel@tonic-gate fprintf(stderr, "Cannot open %s\n", *argv);
180*0Sstevel@tonic-gate error = B_TRUE;
181*0Sstevel@tonic-gate return;
182*0Sstevel@tonic-gate }
183*0Sstevel@tonic-gate /* add all types in this file to our table */
184*0Sstevel@tonic-gate parse_dbg(fp);
185*0Sstevel@tonic-gate }
186*0Sstevel@tonic-gate }
187*0Sstevel@tonic-gate
188*0Sstevel@tonic-gate static char *
namex(char * cp,char ** w)189*0Sstevel@tonic-gate namex(char *cp, char **w)
190*0Sstevel@tonic-gate {
191*0Sstevel@tonic-gate char *new, *orig, c;
192*0Sstevel@tonic-gate int len;
193*0Sstevel@tonic-gate
194*0Sstevel@tonic-gate if (*cp == '\0') {
195*0Sstevel@tonic-gate *w = NULL;
196*0Sstevel@tonic-gate return (cp);
197*0Sstevel@tonic-gate }
198*0Sstevel@tonic-gate
199*0Sstevel@tonic-gate for (c = *cp++; isspace(c); c = *cp++)
200*0Sstevel@tonic-gate ;
201*0Sstevel@tonic-gate orig = --cp;
202*0Sstevel@tonic-gate c = *cp++;
203*0Sstevel@tonic-gate if (isalpha(c) || ispunct(c)) {
204*0Sstevel@tonic-gate for (c = *cp++; isalnum(c) || ispunct(c); c = *cp++)
205*0Sstevel@tonic-gate ;
206*0Sstevel@tonic-gate len = cp - orig;
207*0Sstevel@tonic-gate new = (char *)malloc(len);
208*0Sstevel@tonic-gate while (orig < cp - 1)
209*0Sstevel@tonic-gate *new++ = *orig++;
210*0Sstevel@tonic-gate *new = '\0';
211*0Sstevel@tonic-gate *w = new - (len - 1);
212*0Sstevel@tonic-gate } else if (c != '\0') {
213*0Sstevel@tonic-gate fprintf(stderr, "line %d has bad character %c\n", line, c);
214*0Sstevel@tonic-gate error = B_TRUE;
215*0Sstevel@tonic-gate }
216*0Sstevel@tonic-gate
217*0Sstevel@tonic-gate return (cp);
218*0Sstevel@tonic-gate }
219*0Sstevel@tonic-gate
220*0Sstevel@tonic-gate /*
221*0Sstevel@tonic-gate * checks to see if this field in the struct was requested for by user
222*0Sstevel@tonic-gate * in the .dbg file.
223*0Sstevel@tonic-gate */
224*0Sstevel@tonic-gate struct child *
find_child(struct node * np,char * w)225*0Sstevel@tonic-gate find_child(struct node *np, char *w)
226*0Sstevel@tonic-gate {
227*0Sstevel@tonic-gate struct child *chp;
228*0Sstevel@tonic-gate
229*0Sstevel@tonic-gate for (chp = np->child; chp != NULL; chp = chp->next) {
230*0Sstevel@tonic-gate if (strcmp(chp->name, w) == 0)
231*0Sstevel@tonic-gate return (chp);
232*0Sstevel@tonic-gate }
233*0Sstevel@tonic-gate return (NULL);
234*0Sstevel@tonic-gate }
235*0Sstevel@tonic-gate
236*0Sstevel@tonic-gate static struct tdesc *
find_member(struct tdesc * tdp,char * name)237*0Sstevel@tonic-gate find_member(struct tdesc *tdp, char *name)
238*0Sstevel@tonic-gate {
239*0Sstevel@tonic-gate struct mlist *mlp;
240*0Sstevel@tonic-gate
241*0Sstevel@tonic-gate while (tdp->type == TYPEOF)
242*0Sstevel@tonic-gate tdp = tdp->data.tdesc;
243*0Sstevel@tonic-gate if (tdp->type != STRUCT && tdp->type != UNION)
244*0Sstevel@tonic-gate return (NULL);
245*0Sstevel@tonic-gate for (mlp = tdp->data.members.forw; mlp != NULL; mlp = mlp->next)
246*0Sstevel@tonic-gate if (strcmp(mlp->name, name) == 0)
247*0Sstevel@tonic-gate return (mlp->fdesc);
248*0Sstevel@tonic-gate return (NULL);
249*0Sstevel@tonic-gate }
250*0Sstevel@tonic-gate
251*0Sstevel@tonic-gate /*
252*0Sstevel@tonic-gate * add this field to our table of structs/fields that the user has
253*0Sstevel@tonic-gate * requested in the .dbg files
254*0Sstevel@tonic-gate */
255*0Sstevel@tonic-gate static void
addchild(char * cp,struct node * np)256*0Sstevel@tonic-gate addchild(char *cp, struct node *np)
257*0Sstevel@tonic-gate {
258*0Sstevel@tonic-gate struct child *chp;
259*0Sstevel@tonic-gate char *w;
260*0Sstevel@tonic-gate
261*0Sstevel@tonic-gate chp = malloc(sizeof (*chp));
262*0Sstevel@tonic-gate cp = namex(cp, &w);
263*0Sstevel@tonic-gate chp->name = w;
264*0Sstevel@tonic-gate cp = namex(cp, &w);
265*0Sstevel@tonic-gate if (w == NULL) {
266*0Sstevel@tonic-gate if (chp->name == NULL) {
267*0Sstevel@tonic-gate fprintf(stderr, "NULL child name\n");
268*0Sstevel@tonic-gate exit(1);
269*0Sstevel@tonic-gate }
270*0Sstevel@tonic-gate /* XXX - always convert to upper-case? */
271*0Sstevel@tonic-gate chp->format = uc(chp->name);
272*0Sstevel@tonic-gate } else {
273*0Sstevel@tonic-gate chp->format = w;
274*0Sstevel@tonic-gate }
275*0Sstevel@tonic-gate chp->next = np->child;
276*0Sstevel@tonic-gate np->child = chp;
277*0Sstevel@tonic-gate }
278*0Sstevel@tonic-gate
279*0Sstevel@tonic-gate /*
280*0Sstevel@tonic-gate * add this struct to our table of structs/fields that the user has
281*0Sstevel@tonic-gate * requested in the .dbg files
282*0Sstevel@tonic-gate */
283*0Sstevel@tonic-gate static struct node *
getnode(char * cp)284*0Sstevel@tonic-gate getnode(char *cp)
285*0Sstevel@tonic-gate {
286*0Sstevel@tonic-gate char *w;
287*0Sstevel@tonic-gate struct node *np;
288*0Sstevel@tonic-gate
289*0Sstevel@tonic-gate cp = namex(cp, &w);
290*0Sstevel@tonic-gate np = malloc(sizeof (*np));
291*0Sstevel@tonic-gate np->name = w;
292*0Sstevel@tonic-gate
293*0Sstevel@tonic-gate /*
294*0Sstevel@tonic-gate * XXX - These positional parameters are a hack
295*0Sstevel@tonic-gate * We have two right now for genassym. The back-ends
296*0Sstevel@tonic-gate * can use format and format2 any way they'd like.
297*0Sstevel@tonic-gate */
298*0Sstevel@tonic-gate cp = namex(cp, &w);
299*0Sstevel@tonic-gate np->format = w;
300*0Sstevel@tonic-gate if (w != NULL) {
301*0Sstevel@tonic-gate w = NULL;
302*0Sstevel@tonic-gate cp = namex(cp, &w);
303*0Sstevel@tonic-gate np->format2 = w;
304*0Sstevel@tonic-gate } else {
305*0Sstevel@tonic-gate np->format2 = NULL;
306*0Sstevel@tonic-gate }
307*0Sstevel@tonic-gate np->child = NULL;
308*0Sstevel@tonic-gate return (np);
309*0Sstevel@tonic-gate }
310*0Sstevel@tonic-gate
311*0Sstevel@tonic-gate /*
312*0Sstevel@tonic-gate * Format for .dbg files should be
313*0Sstevel@tonic-gate * Ex:
314*0Sstevel@tonic-gate * seg
315*0Sstevel@tonic-gate * as s_as
316*0Sstevel@tonic-gate * if you wanted the contents of "s_as" (a pointer) to be printed in
317*0Sstevel@tonic-gate * the format of a "as"
318*0Sstevel@tonic-gate */
319*0Sstevel@tonic-gate static void
parse_dbg(FILE * sp)320*0Sstevel@tonic-gate parse_dbg(FILE *sp)
321*0Sstevel@tonic-gate {
322*0Sstevel@tonic-gate char *cp;
323*0Sstevel@tonic-gate struct node *np;
324*0Sstevel@tonic-gate static char linebuf[MAXLINE];
325*0Sstevel@tonic-gate int copy_flag = 0;
326*0Sstevel@tonic-gate int ignore_flag = 0;
327*0Sstevel@tonic-gate size_t c;
328*0Sstevel@tonic-gate
329*0Sstevel@tonic-gate /* grab each line and add them to our table */
330*0Sstevel@tonic-gate for (line = 1; (cp = fgets(linebuf, MAXLINE, sp)) != NULL; line++) {
331*0Sstevel@tonic-gate if (*cp == '\n') {
332*0Sstevel@tonic-gate if (copy_flag)
333*0Sstevel@tonic-gate printf("\n");
334*0Sstevel@tonic-gate continue;
335*0Sstevel@tonic-gate }
336*0Sstevel@tonic-gate if (*cp == '\\') {
337*0Sstevel@tonic-gate if (cp[1] == '#')
338*0Sstevel@tonic-gate printf("%s", (cp + 1));
339*0Sstevel@tonic-gate continue;
340*0Sstevel@tonic-gate }
341*0Sstevel@tonic-gate if (strcmp(cp, "model_end\n") == 0) {
342*0Sstevel@tonic-gate if (ignore_flag)
343*0Sstevel@tonic-gate ignore_flag = 0;
344*0Sstevel@tonic-gate continue;
345*0Sstevel@tonic-gate }
346*0Sstevel@tonic-gate if (ignore_flag)
347*0Sstevel@tonic-gate continue;
348*0Sstevel@tonic-gate c = strlen("model_start ");
349*0Sstevel@tonic-gate if (strncmp(cp, "model_start ", c) == 0) {
350*0Sstevel@tonic-gate if (strncmp(cp + c, model->name, strlen(model->name))
351*0Sstevel@tonic-gate == 0 && *(cp + c + strlen(model->name)) == '\n')
352*0Sstevel@tonic-gate /* model matches */;
353*0Sstevel@tonic-gate else
354*0Sstevel@tonic-gate ignore_flag = 1;
355*0Sstevel@tonic-gate continue;
356*0Sstevel@tonic-gate }
357*0Sstevel@tonic-gate if ((strcmp(cp, "verbatim_begin\n") == 0) ||
358*0Sstevel@tonic-gate (strcmp(cp, "forth_start\n") == 0)) {
359*0Sstevel@tonic-gate copy_flag = 1;
360*0Sstevel@tonic-gate continue;
361*0Sstevel@tonic-gate }
362*0Sstevel@tonic-gate if ((strcmp(cp, "verbatim_end\n") == 0) ||
363*0Sstevel@tonic-gate (strcmp(cp, "forth_end\n") == 0)) {
364*0Sstevel@tonic-gate copy_flag = 0;
365*0Sstevel@tonic-gate continue;
366*0Sstevel@tonic-gate }
367*0Sstevel@tonic-gate if (copy_flag) {
368*0Sstevel@tonic-gate printf("%s", cp);
369*0Sstevel@tonic-gate continue;
370*0Sstevel@tonic-gate }
371*0Sstevel@tonic-gate np = getnode(cp);
372*0Sstevel@tonic-gate for (line++;
373*0Sstevel@tonic-gate ((cp = fgets(linebuf, MAXLINE, sp)) != NULL) &&
374*0Sstevel@tonic-gate *cp != '\n'; line++) {
375*0Sstevel@tonic-gate /* members of struct, union or enum */
376*0Sstevel@tonic-gate addchild(cp, np);
377*0Sstevel@tonic-gate }
378*0Sstevel@tonic-gate printnode(np);
379*0Sstevel@tonic-gate }
380*0Sstevel@tonic-gate }
381*0Sstevel@tonic-gate
382*0Sstevel@tonic-gate static void
printnode(struct node * np)383*0Sstevel@tonic-gate printnode(struct node *np)
384*0Sstevel@tonic-gate {
385*0Sstevel@tonic-gate struct tdesc *tdp;
386*0Sstevel@tonic-gate
387*0Sstevel@tonic-gate tdp = lookupname(np->name);
388*0Sstevel@tonic-gate if (tdp == NULL) {
389*0Sstevel@tonic-gate char *member;
390*0Sstevel@tonic-gate struct tdesc *ptdp;
391*0Sstevel@tonic-gate
392*0Sstevel@tonic-gate if ((member = strchr(np->name, '.')) != NULL) {
393*0Sstevel@tonic-gate *member = '\0';
394*0Sstevel@tonic-gate ptdp = lookupname(np->name);
395*0Sstevel@tonic-gate if (ptdp != NULL)
396*0Sstevel@tonic-gate tdp = find_member(ptdp, member + 1);
397*0Sstevel@tonic-gate *member = '.';
398*0Sstevel@tonic-gate }
399*0Sstevel@tonic-gate if (tdp == NULL) {
400*0Sstevel@tonic-gate fprintf(stderr, "Can't find %s\n", np->name);
401*0Sstevel@tonic-gate error = B_TRUE;
402*0Sstevel@tonic-gate return;
403*0Sstevel@tonic-gate }
404*0Sstevel@tonic-gate }
405*0Sstevel@tonic-gate again:
406*0Sstevel@tonic-gate switch (tdp->type) {
407*0Sstevel@tonic-gate case STRUCT:
408*0Sstevel@tonic-gate case UNION:
409*0Sstevel@tonic-gate ops->do_sou(tdp, np);
410*0Sstevel@tonic-gate break;
411*0Sstevel@tonic-gate case ENUM:
412*0Sstevel@tonic-gate ops->do_enum(tdp, np);
413*0Sstevel@tonic-gate break;
414*0Sstevel@tonic-gate case TYPEOF:
415*0Sstevel@tonic-gate tdp = tdp->data.tdesc;
416*0Sstevel@tonic-gate goto again;
417*0Sstevel@tonic-gate case INTRINSIC:
418*0Sstevel@tonic-gate ops->do_intrinsic(tdp, np);
419*0Sstevel@tonic-gate break;
420*0Sstevel@tonic-gate default:
421*0Sstevel@tonic-gate fprintf(stderr, "%s isn't aggregate\n", np->name);
422*0Sstevel@tonic-gate error = B_TRUE;
423*0Sstevel@tonic-gate break;
424*0Sstevel@tonic-gate }
425*0Sstevel@tonic-gate }
426*0Sstevel@tonic-gate
427*0Sstevel@tonic-gate
428*0Sstevel@tonic-gate char *
convert_format(char * format,char * dfault)429*0Sstevel@tonic-gate convert_format(char *format, char *dfault)
430*0Sstevel@tonic-gate {
431*0Sstevel@tonic-gate static char dot[3] = ".";
432*0Sstevel@tonic-gate
433*0Sstevel@tonic-gate if (format == NULL)
434*0Sstevel@tonic-gate return (dfault);
435*0Sstevel@tonic-gate else if (strlen(format) == 1) {
436*0Sstevel@tonic-gate dot[1] = *format;
437*0Sstevel@tonic-gate return (dot);
438*0Sstevel@tonic-gate } else
439*0Sstevel@tonic-gate return (format);
440*0Sstevel@tonic-gate }
441*0Sstevel@tonic-gate
442*0Sstevel@tonic-gate char *
uc(const char * s)443*0Sstevel@tonic-gate uc(const char *s)
444*0Sstevel@tonic-gate {
445*0Sstevel@tonic-gate char *buf;
446*0Sstevel@tonic-gate int i;
447*0Sstevel@tonic-gate
448*0Sstevel@tonic-gate buf = strdup(s);
449*0Sstevel@tonic-gate for (i = 0; i < strlen(buf); i++)
450*0Sstevel@tonic-gate buf[i] = toupper(buf[i]);
451*0Sstevel@tonic-gate buf[i] = '\0';
452*0Sstevel@tonic-gate return (buf);
453*0Sstevel@tonic-gate }
454