xref: /titanic_41/usr/src/cmd/sgs/libelf/misc/args.c (revision 7c478bd95313f5f23a4c958a745db2134aa03244)
1*7c478bd9Sstevel@tonic-gate /*
2*7c478bd9Sstevel@tonic-gate  * CDDL HEADER START
3*7c478bd9Sstevel@tonic-gate  *
4*7c478bd9Sstevel@tonic-gate  * The contents of this file are subject to the terms of the
5*7c478bd9Sstevel@tonic-gate  * Common Development and Distribution License, Version 1.0 only
6*7c478bd9Sstevel@tonic-gate  * (the "License").  You may not use this file except in compliance
7*7c478bd9Sstevel@tonic-gate  * with the License.
8*7c478bd9Sstevel@tonic-gate  *
9*7c478bd9Sstevel@tonic-gate  * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10*7c478bd9Sstevel@tonic-gate  * or http://www.opensolaris.org/os/licensing.
11*7c478bd9Sstevel@tonic-gate  * See the License for the specific language governing permissions
12*7c478bd9Sstevel@tonic-gate  * and limitations under the License.
13*7c478bd9Sstevel@tonic-gate  *
14*7c478bd9Sstevel@tonic-gate  * When distributing Covered Code, include this CDDL HEADER in each
15*7c478bd9Sstevel@tonic-gate  * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16*7c478bd9Sstevel@tonic-gate  * If applicable, add the following below this CDDL HEADER, with the
17*7c478bd9Sstevel@tonic-gate  * fields enclosed by brackets "[]" replaced with your own identifying
18*7c478bd9Sstevel@tonic-gate  * information: Portions Copyright [yyyy] [name of copyright owner]
19*7c478bd9Sstevel@tonic-gate  *
20*7c478bd9Sstevel@tonic-gate  * CDDL HEADER END
21*7c478bd9Sstevel@tonic-gate  */
22*7c478bd9Sstevel@tonic-gate /*
23*7c478bd9Sstevel@tonic-gate  *	Copyright (c) 1988 AT&T
24*7c478bd9Sstevel@tonic-gate  *	  All Rights Reserved
25*7c478bd9Sstevel@tonic-gate  *
26*7c478bd9Sstevel@tonic-gate  *
27*7c478bd9Sstevel@tonic-gate  *	Copyright (c) 1998 by Sun Microsystems, Inc.
28*7c478bd9Sstevel@tonic-gate  *	All rights reserved.
29*7c478bd9Sstevel@tonic-gate  */
30*7c478bd9Sstevel@tonic-gate #pragma ident	"%Z%%M%	%I%	%E% SMI" 	/* SVr4.0 1.2	*/
31*7c478bd9Sstevel@tonic-gate 
32*7c478bd9Sstevel@tonic-gate #include	<ctype.h>
33*7c478bd9Sstevel@tonic-gate #include	<stdlib.h>
34*7c478bd9Sstevel@tonic-gate #include	<string.h>
35*7c478bd9Sstevel@tonic-gate #include	"elf_dem.h"
36*7c478bd9Sstevel@tonic-gate #include	"String.h"
37*7c478bd9Sstevel@tonic-gate #include	"msg.h"
38*7c478bd9Sstevel@tonic-gate 
39*7c478bd9Sstevel@tonic-gate /* This structure is used to keep
40*7c478bd9Sstevel@tonic-gate  * track of pointers to argument
41*7c478bd9Sstevel@tonic-gate  * descriptions in the mangled string.
42*7c478bd9Sstevel@tonic-gate  * This is needed for N and T encodings
43*7c478bd9Sstevel@tonic-gate  * to work.
44*7c478bd9Sstevel@tonic-gate  */
45*7c478bd9Sstevel@tonic-gate typedef struct {
46*7c478bd9Sstevel@tonic-gate 	char *list[10];
47*7c478bd9Sstevel@tonic-gate 	int pos;
48*7c478bd9Sstevel@tonic-gate } Place;
49*7c478bd9Sstevel@tonic-gate 
50*7c478bd9Sstevel@tonic-gate static Place here;
51*7c478bd9Sstevel@tonic-gate 
52*7c478bd9Sstevel@tonic-gate /* Strings and flags needed by the argument demangles.  The declarator
53*7c478bd9Sstevel@tonic-gate  * is built up in ptr.  Type modifiers are held in the flag fields.
54*7c478bd9Sstevel@tonic-gate  * The type itself is passed in separately.
55*7c478bd9Sstevel@tonic-gate  */
56*7c478bd9Sstevel@tonic-gate typedef struct {
57*7c478bd9Sstevel@tonic-gate 	String *ptr;
58*7c478bd9Sstevel@tonic-gate 	int Sign,Uns,Cons,Vol;
59*7c478bd9Sstevel@tonic-gate } Arg_Remem;
60*7c478bd9Sstevel@tonic-gate 
61*7c478bd9Sstevel@tonic-gate /* initialize Arg_Remem */
62*7c478bd9Sstevel@tonic-gate static void
mkar(r)63*7c478bd9Sstevel@tonic-gate mkar(r)
64*7c478bd9Sstevel@tonic-gate Arg_Remem *r;
65*7c478bd9Sstevel@tonic-gate {
66*7c478bd9Sstevel@tonic-gate 	r->ptr = mk_String((String *)0);
67*7c478bd9Sstevel@tonic-gate 	r->Sign = r->Uns = r->Cons = r->Vol = 0;
68*7c478bd9Sstevel@tonic-gate }
69*7c478bd9Sstevel@tonic-gate 
70*7c478bd9Sstevel@tonic-gate /* free data for Arg_Remem */
71*7c478bd9Sstevel@tonic-gate static void
delar(r)72*7c478bd9Sstevel@tonic-gate delar(r)
73*7c478bd9Sstevel@tonic-gate Arg_Remem *r;
74*7c478bd9Sstevel@tonic-gate {
75*7c478bd9Sstevel@tonic-gate 	free_String(r->ptr);
76*7c478bd9Sstevel@tonic-gate }
77*7c478bd9Sstevel@tonic-gate 
78*7c478bd9Sstevel@tonic-gate /* This routine formats a single argument
79*7c478bd9Sstevel@tonic-gate  * on the buffer sptr.
80*7c478bd9Sstevel@tonic-gate  * c is the type or class name, n is its length.
81*7c478bd9Sstevel@tonic-gate  */
82*7c478bd9Sstevel@tonic-gate static void
nsetarg(String ** sptr,Arg_Remem * r,const char * c,int n)83*7c478bd9Sstevel@tonic-gate nsetarg(String ** sptr, Arg_Remem * r, const char * c, int n)
84*7c478bd9Sstevel@tonic-gate {
85*7c478bd9Sstevel@tonic-gate 	r->ptr = nprep_String(c, r->ptr, n);
86*7c478bd9Sstevel@tonic-gate 	if(r->Cons)
87*7c478bd9Sstevel@tonic-gate 		r->ptr = prep_String(MSG_ORIG(MSG_STR_CONST_1), r->ptr);
88*7c478bd9Sstevel@tonic-gate 	if(r->Vol)
89*7c478bd9Sstevel@tonic-gate 		r->ptr = prep_String(MSG_ORIG(MSG_STR_VOLATILE_1), r->ptr);
90*7c478bd9Sstevel@tonic-gate 	if(r->Uns)
91*7c478bd9Sstevel@tonic-gate 		r->ptr = prep_String(MSG_ORIG(MSG_STR_UNSIGNED), r->ptr);
92*7c478bd9Sstevel@tonic-gate 	else if(r->Sign)
93*7c478bd9Sstevel@tonic-gate 		r->ptr = prep_String(MSG_ORIG(MSG_STR_SIGNED), r->ptr);
94*7c478bd9Sstevel@tonic-gate 	*sptr = app_String(*sptr,PTR(r->ptr));
95*7c478bd9Sstevel@tonic-gate 	delar(r);
96*7c478bd9Sstevel@tonic-gate }
97*7c478bd9Sstevel@tonic-gate 
98*7c478bd9Sstevel@tonic-gate /* This routine formats a single argument
99*7c478bd9Sstevel@tonic-gate  * on the buffer sptr.
100*7c478bd9Sstevel@tonic-gate  * c is the null terminated type or class name.
101*7c478bd9Sstevel@tonic-gate  */
102*7c478bd9Sstevel@tonic-gate static void
setarg(String ** sptr,Arg_Remem * r,const char * c)103*7c478bd9Sstevel@tonic-gate setarg(String ** sptr, Arg_Remem * r, const char * c)
104*7c478bd9Sstevel@tonic-gate {
105*7c478bd9Sstevel@tonic-gate 	nsetarg(sptr, r, c, ID_NAME_MAX);
106*7c478bd9Sstevel@tonic-gate }
107*7c478bd9Sstevel@tonic-gate 
108*7c478bd9Sstevel@tonic-gate 
109*7c478bd9Sstevel@tonic-gate /* Demangle a single function argument.
110*7c478bd9Sstevel@tonic-gate  * Returns the number of characters processed from c.
111*7c478bd9Sstevel@tonic-gate  */
112*7c478bd9Sstevel@tonic-gate int
demangle_doarg(sptr,c)113*7c478bd9Sstevel@tonic-gate demangle_doarg(sptr,c)
114*7c478bd9Sstevel@tonic-gate String **sptr;
115*7c478bd9Sstevel@tonic-gate char *c;
116*7c478bd9Sstevel@tonic-gate {
117*7c478bd9Sstevel@tonic-gate 	register int i;
118*7c478bd9Sstevel@tonic-gate 	Arg_Remem ar;
119*7c478bd9Sstevel@tonic-gate 	mkar(&ar);
120*7c478bd9Sstevel@tonic-gate 
121*7c478bd9Sstevel@tonic-gate 	if(here.pos < 10 && here.pos >= 0)
122*7c478bd9Sstevel@tonic-gate 		here.list[here.pos++] = c;
123*7c478bd9Sstevel@tonic-gate 
124*7c478bd9Sstevel@tonic-gate 	for(i=0;c[i];i++) {
125*7c478bd9Sstevel@tonic-gate 		/* Loop until you find a type.
126*7c478bd9Sstevel@tonic-gate 		   Then call setarg and return.
127*7c478bd9Sstevel@tonic-gate 		*/
128*7c478bd9Sstevel@tonic-gate 		switch(c[i]) {
129*7c478bd9Sstevel@tonic-gate 
130*7c478bd9Sstevel@tonic-gate 		case 'T':
131*7c478bd9Sstevel@tonic-gate 			{
132*7c478bd9Sstevel@tonic-gate 				Place tmp;
133*7c478bd9Sstevel@tonic-gate 				tmp = here;
134*7c478bd9Sstevel@tonic-gate 				here.pos = c[1] - '1';
135*7c478bd9Sstevel@tonic-gate 				if(here.pos < 0 || here.pos >= tmp.pos-1) {
136*7c478bd9Sstevel@tonic-gate 					delar(&ar);
137*7c478bd9Sstevel@tonic-gate 					return -1;
138*7c478bd9Sstevel@tonic-gate 				}
139*7c478bd9Sstevel@tonic-gate 				(void) demangle_doarg(sptr,here.list[here.pos]);
140*7c478bd9Sstevel@tonic-gate 				here = tmp;
141*7c478bd9Sstevel@tonic-gate 				delar(&ar);
142*7c478bd9Sstevel@tonic-gate 				return 2;
143*7c478bd9Sstevel@tonic-gate 			}
144*7c478bd9Sstevel@tonic-gate 		case 'N':
145*7c478bd9Sstevel@tonic-gate 			{
146*7c478bd9Sstevel@tonic-gate 				Place tmp;
147*7c478bd9Sstevel@tonic-gate 				int cycles,pos;
148*7c478bd9Sstevel@tonic-gate 				cycles = c[1] - '0'; pos = c[2] - '1';
149*7c478bd9Sstevel@tonic-gate 				here.pos += cycles - 1;
150*7c478bd9Sstevel@tonic-gate 				tmp = here;
151*7c478bd9Sstevel@tonic-gate 				if(cycles <= 1 || cycles > 9 || pos < 0 || pos >= tmp.pos-1) {
152*7c478bd9Sstevel@tonic-gate 					delar(&ar);
153*7c478bd9Sstevel@tonic-gate 					return -1;
154*7c478bd9Sstevel@tonic-gate 				}
155*7c478bd9Sstevel@tonic-gate 				while(cycles--) {
156*7c478bd9Sstevel@tonic-gate 					here = tmp;
157*7c478bd9Sstevel@tonic-gate 					here.pos = pos;
158*7c478bd9Sstevel@tonic-gate 					(void) demangle_doarg(sptr,here.list[here.pos]);
159*7c478bd9Sstevel@tonic-gate 					(*sptr) = app_String(*sptr,
160*7c478bd9Sstevel@tonic-gate 					    MSG_ORIG(MSG_STR_COMMA));
161*7c478bd9Sstevel@tonic-gate 				}
162*7c478bd9Sstevel@tonic-gate 				*sptr = trunc_String(*sptr, 1);
163*7c478bd9Sstevel@tonic-gate 				here = tmp;
164*7c478bd9Sstevel@tonic-gate 				delar(&ar);
165*7c478bd9Sstevel@tonic-gate 				return 3;
166*7c478bd9Sstevel@tonic-gate 			}
167*7c478bd9Sstevel@tonic-gate 
168*7c478bd9Sstevel@tonic-gate 		/* Qualifiers to type names */
169*7c478bd9Sstevel@tonic-gate 		case 'S':
170*7c478bd9Sstevel@tonic-gate 			ar.Sign = 1;
171*7c478bd9Sstevel@tonic-gate 			break;
172*7c478bd9Sstevel@tonic-gate 		case 'U':
173*7c478bd9Sstevel@tonic-gate 			ar.Uns = 1;
174*7c478bd9Sstevel@tonic-gate 			break;
175*7c478bd9Sstevel@tonic-gate 		case 'C':
176*7c478bd9Sstevel@tonic-gate 			ar.Cons = 1;
177*7c478bd9Sstevel@tonic-gate 			break;
178*7c478bd9Sstevel@tonic-gate 		case 'V':
179*7c478bd9Sstevel@tonic-gate 			ar.Vol = 1;
180*7c478bd9Sstevel@tonic-gate 			break;
181*7c478bd9Sstevel@tonic-gate 
182*7c478bd9Sstevel@tonic-gate 		/* Pointers, references, and Member Pointers */
183*7c478bd9Sstevel@tonic-gate 		case 'P':
184*7c478bd9Sstevel@tonic-gate 		case 'R':
185*7c478bd9Sstevel@tonic-gate 		case 'M':
186*7c478bd9Sstevel@tonic-gate 			if(ar.Cons) {
187*7c478bd9Sstevel@tonic-gate 				ar.ptr = prep_String(MSG_ORIG(MSG_STR_CONST_2),
188*7c478bd9Sstevel@tonic-gate 				    ar.ptr);
189*7c478bd9Sstevel@tonic-gate 				ar.Cons = 0;
190*7c478bd9Sstevel@tonic-gate 			}
191*7c478bd9Sstevel@tonic-gate 			if(ar.Vol) {
192*7c478bd9Sstevel@tonic-gate 				ar.ptr =
193*7c478bd9Sstevel@tonic-gate 				    prep_String(MSG_ORIG(MSG_STR_VOLATILE_2),
194*7c478bd9Sstevel@tonic-gate 				    ar.ptr);
195*7c478bd9Sstevel@tonic-gate 				ar.Vol = 0;
196*7c478bd9Sstevel@tonic-gate 			}
197*7c478bd9Sstevel@tonic-gate 			if(c[i] == 'P')
198*7c478bd9Sstevel@tonic-gate 				ar.ptr = prep_String(MSG_ORIG(MSG_STR_STAR),
199*7c478bd9Sstevel@tonic-gate 				    ar.ptr);
200*7c478bd9Sstevel@tonic-gate 			else if(c[i] == 'R')
201*7c478bd9Sstevel@tonic-gate 				ar.ptr = prep_String(MSG_ORIG(MSG_STR_AMP),
202*7c478bd9Sstevel@tonic-gate 				    ar.ptr);
203*7c478bd9Sstevel@tonic-gate 			else {
204*7c478bd9Sstevel@tonic-gate 				int cnt = 0;
205*7c478bd9Sstevel@tonic-gate 				char *s;
206*7c478bd9Sstevel@tonic-gate 				ar.ptr =
207*7c478bd9Sstevel@tonic-gate 				    prep_String(MSG_ORIG(MSG_STR_DBLCOLSTAR),
208*7c478bd9Sstevel@tonic-gate 				    ar.ptr);
209*7c478bd9Sstevel@tonic-gate 				/* Skip over the 'M' */
210*7c478bd9Sstevel@tonic-gate 				i++;
211*7c478bd9Sstevel@tonic-gate 				cnt = strtol(c+i, &s, 10);
212*7c478bd9Sstevel@tonic-gate 				i = s - c;
213*7c478bd9Sstevel@tonic-gate 				ar.ptr = nprep_String(c+i,ar.ptr,cnt);
214*7c478bd9Sstevel@tonic-gate 				ar.ptr = prep_String(MSG_ORIG(MSG_STR_SPACE),
215*7c478bd9Sstevel@tonic-gate 				    ar.ptr);
216*7c478bd9Sstevel@tonic-gate 				i += cnt;
217*7c478bd9Sstevel@tonic-gate 				/* The loop increments i */
218*7c478bd9Sstevel@tonic-gate 				i--;
219*7c478bd9Sstevel@tonic-gate 			}
220*7c478bd9Sstevel@tonic-gate 			break;
221*7c478bd9Sstevel@tonic-gate 
222*7c478bd9Sstevel@tonic-gate 		/* Demangle for basic built-in types */
223*7c478bd9Sstevel@tonic-gate 		case 'i':
224*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_INT));
225*7c478bd9Sstevel@tonic-gate 			return i + 1;
226*7c478bd9Sstevel@tonic-gate 		case 'c':
227*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_CHAR));
228*7c478bd9Sstevel@tonic-gate 			return i + 1;
229*7c478bd9Sstevel@tonic-gate 		case 's':
230*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_SHORT));
231*7c478bd9Sstevel@tonic-gate 			return i + 1;
232*7c478bd9Sstevel@tonic-gate 		case 'l':
233*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_LONG));
234*7c478bd9Sstevel@tonic-gate 			return i + 1;
235*7c478bd9Sstevel@tonic-gate 		case 'f':
236*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_FLOAT));
237*7c478bd9Sstevel@tonic-gate 			return i + 1;
238*7c478bd9Sstevel@tonic-gate 		case 'd':
239*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_DOUBLE));
240*7c478bd9Sstevel@tonic-gate 			return i + 1;
241*7c478bd9Sstevel@tonic-gate 		case 'r':
242*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_LONGDOUBLE));
243*7c478bd9Sstevel@tonic-gate 			return i + 1;
244*7c478bd9Sstevel@tonic-gate 
245*7c478bd9Sstevel@tonic-gate 		/* Class encodings */
246*7c478bd9Sstevel@tonic-gate 		case '1': case '2': case '3':
247*7c478bd9Sstevel@tonic-gate 		case '4': case '5': case '6':
248*7c478bd9Sstevel@tonic-gate 		case '7': case '8': case '9':
249*7c478bd9Sstevel@tonic-gate 			{
250*7c478bd9Sstevel@tonic-gate 				int cnt = 0;
251*7c478bd9Sstevel@tonic-gate 				char *s;
252*7c478bd9Sstevel@tonic-gate 				cnt = strtol(c+i, &s, 10);
253*7c478bd9Sstevel@tonic-gate 				i = s - c;
254*7c478bd9Sstevel@tonic-gate 				if ((int) strlen(c+i) < cnt) {
255*7c478bd9Sstevel@tonic-gate 					delar(&ar);
256*7c478bd9Sstevel@tonic-gate 					return -1;
257*7c478bd9Sstevel@tonic-gate 				}
258*7c478bd9Sstevel@tonic-gate 				nsetarg(sptr,&ar,c+i,cnt);
259*7c478bd9Sstevel@tonic-gate 				return i+cnt;
260*7c478bd9Sstevel@tonic-gate 			}
261*7c478bd9Sstevel@tonic-gate 
262*7c478bd9Sstevel@tonic-gate 		/* Ellipsis and void */
263*7c478bd9Sstevel@tonic-gate 		case 'e':
264*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_ELIPSE));
265*7c478bd9Sstevel@tonic-gate 			return i + 1;
266*7c478bd9Sstevel@tonic-gate 		case 'v':
267*7c478bd9Sstevel@tonic-gate 			setarg(sptr, &ar, MSG_ORIG(MSG_STR_VOID));
268*7c478bd9Sstevel@tonic-gate 			return i + 1;
269*7c478bd9Sstevel@tonic-gate 
270*7c478bd9Sstevel@tonic-gate 		/* Arrays */
271*7c478bd9Sstevel@tonic-gate 		case 'A':
272*7c478bd9Sstevel@tonic-gate 			if(*PTR(ar.ptr)) {
273*7c478bd9Sstevel@tonic-gate 				ar.ptr = prep_String(MSG_ORIG(MSG_STR_OPENPAR),
274*7c478bd9Sstevel@tonic-gate 				   ar.ptr);
275*7c478bd9Sstevel@tonic-gate 				ar.ptr = app_String(ar.ptr,
276*7c478bd9Sstevel@tonic-gate 				   MSG_ORIG(MSG_STR_CLOSEPAR));
277*7c478bd9Sstevel@tonic-gate 			}
278*7c478bd9Sstevel@tonic-gate 			ar.ptr = app_String(ar.ptr, MSG_ORIG(MSG_STR_OPENBRAK));
279*7c478bd9Sstevel@tonic-gate 			{
280*7c478bd9Sstevel@tonic-gate 				int cnt = 0;
281*7c478bd9Sstevel@tonic-gate 				i++;
282*7c478bd9Sstevel@tonic-gate 				while(isdigit(c[i+cnt]))
283*7c478bd9Sstevel@tonic-gate 					cnt++;
284*7c478bd9Sstevel@tonic-gate 				ar.ptr = napp_String(ar.ptr,c+i,cnt);
285*7c478bd9Sstevel@tonic-gate 				i += cnt;
286*7c478bd9Sstevel@tonic-gate 				if(c[i] != '_') {
287*7c478bd9Sstevel@tonic-gate 					delar(&ar);
288*7c478bd9Sstevel@tonic-gate 					return -1;
289*7c478bd9Sstevel@tonic-gate 				}
290*7c478bd9Sstevel@tonic-gate 			}
291*7c478bd9Sstevel@tonic-gate 			ar.ptr = app_String(ar.ptr,
292*7c478bd9Sstevel@tonic-gate 			    MSG_ORIG(MSG_STR_CLOSEBRAK));
293*7c478bd9Sstevel@tonic-gate 			break;
294*7c478bd9Sstevel@tonic-gate 
295*7c478bd9Sstevel@tonic-gate 		/* Functions
296*7c478bd9Sstevel@tonic-gate 		 * This will always be called as a pointer
297*7c478bd9Sstevel@tonic-gate 		 * to a function.
298*7c478bd9Sstevel@tonic-gate 		 */
299*7c478bd9Sstevel@tonic-gate 		case 'F':
300*7c478bd9Sstevel@tonic-gate 			ar.ptr = prep_String(MSG_ORIG(MSG_STR_OPENPAR), ar.ptr);
301*7c478bd9Sstevel@tonic-gate 			ar.ptr = app_String(ar.ptr, MSG_ORIG(MSG_STR_CLOSEPAR));
302*7c478bd9Sstevel@tonic-gate 			{
303*7c478bd9Sstevel@tonic-gate 				Place tmp;
304*7c478bd9Sstevel@tonic-gate 				tmp = here;
305*7c478bd9Sstevel@tonic-gate 				i++;
306*7c478bd9Sstevel@tonic-gate 				i += demangle_doargs(&ar.ptr,c+i);
307*7c478bd9Sstevel@tonic-gate 				if(c[i] != '_') {
308*7c478bd9Sstevel@tonic-gate 					delar(&ar);
309*7c478bd9Sstevel@tonic-gate 					return -1;
310*7c478bd9Sstevel@tonic-gate 				}
311*7c478bd9Sstevel@tonic-gate 				here = tmp;
312*7c478bd9Sstevel@tonic-gate 			}
313*7c478bd9Sstevel@tonic-gate 			break;
314*7c478bd9Sstevel@tonic-gate 
315*7c478bd9Sstevel@tonic-gate 		/* Needed when this is called to demangle
316*7c478bd9Sstevel@tonic-gate 		 * an argument of a pointer to a function.
317*7c478bd9Sstevel@tonic-gate 		 */
318*7c478bd9Sstevel@tonic-gate 		case '_':
319*7c478bd9Sstevel@tonic-gate 			delar(&ar);
320*7c478bd9Sstevel@tonic-gate 			return 0;
321*7c478bd9Sstevel@tonic-gate 
322*7c478bd9Sstevel@tonic-gate 		default:
323*7c478bd9Sstevel@tonic-gate 			delar(&ar);
324*7c478bd9Sstevel@tonic-gate 			return -1;
325*7c478bd9Sstevel@tonic-gate 		}
326*7c478bd9Sstevel@tonic-gate 	}
327*7c478bd9Sstevel@tonic-gate 
328*7c478bd9Sstevel@tonic-gate 	/* Did the argument list terminate properly? */
329*7c478bd9Sstevel@tonic-gate 	{
330*7c478bd9Sstevel@tonic-gate 		int rc = 0;
331*7c478bd9Sstevel@tonic-gate 		if(*PTR(ar.ptr) || ar.Uns || ar.Sign || ar.Cons || ar.Vol)
332*7c478bd9Sstevel@tonic-gate 			rc = -1;
333*7c478bd9Sstevel@tonic-gate 		delar(&ar);
334*7c478bd9Sstevel@tonic-gate 		return rc;
335*7c478bd9Sstevel@tonic-gate 	}
336*7c478bd9Sstevel@tonic-gate }
337*7c478bd9Sstevel@tonic-gate 
338*7c478bd9Sstevel@tonic-gate /* This function is called to demangle
339*7c478bd9Sstevel@tonic-gate  * an argument list.
340*7c478bd9Sstevel@tonic-gate  * Returns the number of characters processed from c.
341*7c478bd9Sstevel@tonic-gate  */
342*7c478bd9Sstevel@tonic-gate int
demangle_doargs(sptr,c)343*7c478bd9Sstevel@tonic-gate demangle_doargs(sptr,c)
344*7c478bd9Sstevel@tonic-gate String **sptr;
345*7c478bd9Sstevel@tonic-gate char *c;
346*7c478bd9Sstevel@tonic-gate {
347*7c478bd9Sstevel@tonic-gate 	int i,n = 0;
348*7c478bd9Sstevel@tonic-gate 	here.pos = 0;
349*7c478bd9Sstevel@tonic-gate 
350*7c478bd9Sstevel@tonic-gate 	*sptr = app_String(*sptr,MSG_ORIG(MSG_STR_OPENPAR));
351*7c478bd9Sstevel@tonic-gate 	while(*c && (i = demangle_doarg(sptr,c)) > 0) {
352*7c478bd9Sstevel@tonic-gate 		c += i;
353*7c478bd9Sstevel@tonic-gate 		n += i;
354*7c478bd9Sstevel@tonic-gate 		(*sptr) = app_String(*sptr,(*c && *c == 'e') ?
355*7c478bd9Sstevel@tonic-gate 		    MSG_ORIG(MSG_STR_SPACE) : MSG_ORIG(MSG_STR_COMMA));
356*7c478bd9Sstevel@tonic-gate 	}
357*7c478bd9Sstevel@tonic-gate 
358*7c478bd9Sstevel@tonic-gate 	if(i < 0)
359*7c478bd9Sstevel@tonic-gate 		return -1;
360*7c478bd9Sstevel@tonic-gate 
361*7c478bd9Sstevel@tonic-gate 	*sptr = app_String(trunc_String(*sptr, 1), MSG_ORIG(MSG_STR_CLOSEPAR));
362*7c478bd9Sstevel@tonic-gate 
363*7c478bd9Sstevel@tonic-gate 	return n;
364*7c478bd9Sstevel@tonic-gate }
365